Breno Ferreira

Opniões e códigos de um desenvolvedor de software .NET.

Criando Scaffolder customizado para o WCF WebAPI

leave a comment »

Olá pessoal,

No último post falei um pouco sobre como customizar um template do MvcScaffolding. Hoje irei explicar como podemos criar um Scaffolder totalmente novo, com funcionalidades nada relacionadas ao ASP.NET MVC. Irei demonstrar rapidamente como voce pode criar um Scaffolder para gerar código para serviços REST utilizando o WCF WebAPI.

Para quem não conhece o WCF WebAPI, recomendo ler um post do Israel Aece que explica muito bem alguns conceitos básicos.

Criando um Custom Scaffolder

Para criarmos um Custom Scaffolder, basta executarmos o seguinte comando no Package Manager Console (depois de ter adicionado o pacote MvcScaffolding é claro):

Gerar Custom Scaffolder
  1. Scaffold CustomScaffolder RestfulService

Esse comando basicamente é um Scaffolder de Scaffolders, ou seja, ele gera um Scaffolder customizado.

No Solution Explorer, agora teremos a seguinte estrutura de arquivos:

image_thumb1

Os arquivos marcados em amarelo foram gerados pelo MvcScaffolding. Um arquivo é o template T4 que possui o template do arquivo de saída, e outro é um arquivo Powershell (.ps1) que irá ser chamado quando executarmos o comando para utilizarmos esse Scaffolder.

O código PowerShell ficou assim:

Default Custom Scaffolder
  1. [T4Scaffolding.Scaffolder(Description = "Enter a description of RestfulService here")][CmdletBinding()]
  2. param(        
  3.     [string]$Project,
  4.     [string]$CodeLanguage,
  5.     [string[]]$TemplateFolders,
  6.     [switch]$Force = $false
  7. )
  8.  
  9. $outputPath = "ExampleOutput"
  10. $namespace = (Get-Project $Project).Properties.Item("DefaultNamespace").Value
  11.  
  12. Add-ProjectItemViaTemplate $outputPath -Template RestfulServiceTemplate `
  13.     -Model @{ Namespace = $namespace; ExampleValue = "Hello, world!" } `
  14.     -SuccessMessage "Added RestfulService output at {0}" `
  15.     -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force

O Comando mais importante aqui é o Add-ProjectItemViaTemplate, que irá gerar o código baseado no Template T4. Esse comando recebe alguns parâmetros importantes:
$outputPath: caminho onde o arquivo será gerado
-Template: Nome do template T4
-Model: dados que são passados para o template T4 como parâmetros para gerar o código
 
Para gerar o serviço com o WebAPI, precisamos de alguns parâmetros para o comando PowerShell:
Service Scaffolder Parameters
  1. [T4Scaffolding.Scaffolder(Description = "Creates a Restful service using WCF WebApi")][CmdletBinding()]
  2. param(
  3.     [parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ModelType,
  4.     [string]$DbContextType,        
  5.     [string]$Project,
  6.     [string]$CodeLanguage,
  7.     [switch]$NoChildItems = $false,
  8.     [string[]]$TemplateFolders,
  9.     [switch]$Force = $false
  10. )

O primeiro parâmetro é o tipo do nosso Model, o segundo é o tipo de algum DbContext do EntityFramework já existente. Note que o primeiro parâmetro é obrigatório.

Não vou entrar em todos os detalhes do script Powershell, senão o post ficaria muito longo, mas o comando para gerarmos o código do serviço é o seguinte:

Gerando o código do serviço
  1. Add-ProjectItemViaTemplate $outputPath -Template RestfulServiceTemplate `
  2.     -Model @{
  3.         ServiceName = $serviceName;
  4.         RepositoryName = $repositoryName;
  5.         ModelType = [MarshalByRefObject]$foundModelType;
  6.         PrimaryKey = [string]$primaryKey;
  7.         DefaultNamespace = $defaultNamespace;
  8.         ModelTypeNamespace = $modelTypeNamespace;
  9.         ServiceNamespace = $serviceNamespace;
  10.          } `
  11.     -SuccessMessage "Added RestfulService output at {0}" `
  12.     -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force:$Force

Passamos como informações para o template T4 os seguintes dados:

  • ServiceName: Nome do tipo do nosso serviço (ex: PersonService)
  • RepositoryName: Nome do tipo do repositório (ex: PersonRepository)
  • ModelType: Tipo do modelo (ex: Person)
  • Primary Key: Propriedade que representa a chave primária no banco (ex: ID)
  • Default Namespace: Namespace padrão do projeto
  • ModelTypeNamespace: Namespace onde o tipo do nosso Model está localizado
  • ServiceNamespace: Namespace onde o serviço estará localizado (DefaultNamespace + “Services”)

Esse comando irá ler o template T4 e gerar um arquivo de saída com o serviço WCF WebAPI.

Uma parte desse template pode ser vista no código abaixo:

Code Snippet
  1.  [ServiceContract]
  2. public class <#= Model.ServiceName #> : I<#= Model.ServiceName #>
  3. {
  4.      private readonly I<#= repositoryName #> <#= repositoryVariableName #>;
  5.      
  6.      //if you are using Dependency Injection, you can delete the following constructor.
  7.      public <#= Model.ServiceName #> ()
  8.          : this(new <#= repositoryName #>())
  9.      {
  10.      }
  11.      
  12.      public <#= Model.ServiceName #> (I<#= repositoryName #> <#= repositoryVariableName #>)
  13.      {
  14.          this.<#= repositoryVariableName #> = <#= repositoryVariableName #>;
  15.      }
  16.      
  17.      [WebGet(UriTemplate="")]
  18.      public IQueryable< <#= modelName #> > GetAll()
  19.      {
  20.          return this.<#= repositoryVariableName #>.All;
  21.      }

Para quem quiser ver maiores detalhes do Scaffolder, criei um projeto no Codeplex e o código fonte complate está disponível lá. Basta entrar no site: http://servicescaffolder.codeplex.com/

Quem quiser utilizar esse Scaffolder, pode fazer uso do Nuget e referenciar o pacote:

Install-Package ServiceScaffolder

Scaffold RestfulService <Model>

Abraços

Breno

Written by Breno Ferreira

14/08/2011 at 15:16

Posted in Dev

Tagged with , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s