Criando templates no Visual Studio
Criar templates no Visual Studio é a forma mais simples de parar de copiar e colar a mesma estrutura de arquivos a cada nova funcionalidade. Neste artigo, você vai montar um item template no Visual Studio 2019 que gera interface, request e implementação de um serviço de uma só vez.
O nosso dia a dia como dev é uma correria, pulando de um projeto para outro. Com isso, vêm as cópias de estruturas e de códigos existentes para criar algo novo.
Basicamente, copiamos o esqueleto de arquivos e depois renomeamos tudo para, só então, desenvolver o que realmente importa. Esse processo é natural, mas também muito repetitivo.
Por que criar templates no Visual Studio
Seria uma maravilha se, com um clique em New Item e a escolha de um arquivo, o Visual Studio 2019 criasse toda a estrutura para nós. Então comemore, pois esse dia chegou.
Os templates no Visual Studio fazem exatamente isso. Em outras palavras, você define uma vez o esqueleto dos arquivos e o IDE repete esse esqueleto sempre que precisar.
Assim, você melhora a produtividade do dia a dia e padroniza o código da equipe. Além disso, reduz erros bobos de renomeação, como uma classe que ficou com o nome do serviço antigo.
Item template e project template
A documentação da Microsoft separa os modelos em dois tipos. Os project templates aparecem na criação de um novo projeto, enquanto os item templates aparecem na janela Add New Item.
Neste tutorial, vamos trabalhar com um item template. Afinal, a ideia é adicionar novos arquivos a um projeto que já existe, e não criar um projeto do zero.
A documentação também explica que um item template representa um único item, mas esse item pode ter vários arquivos. É justamente esse recurso, chamado de item template com múltiplos arquivos, que vamos usar.
O que o nosso template vai gerar
Basicamente, vamos criar um template de serviço simples. A partir do Visual Studio 2019, ele vai gerar os seguintes arquivos:
- Interface, onde fica declarada a assinatura do método.
- Classe de request, que é o objeto enviado para esse serviço.
- Classe de implementação, que implementa a interface e recebe o request como parâmetro.
É algo bem próximo do recurso de scaffold do ASP.NET Core MVC, que gera os controllers com as ações de forma automática. No entanto, aqui você controla cada linha do que será gerado.
Preparando o projeto para os templates no Visual Studio
Primeiro, crie um projeto do tipo Console Application. Esse tipo de projeto facilita a criação dos arquivos que envolvem a nossa automação de template.
Vou criar o projeto pelo Visual Studio 2019, porém nada impede de criá-lo pela .NET CLI. Se você ainda não tem o SDK instalado, veja o artigo sobre instalação e primeiros passos com .NET.
Depois que o projeto estiver criado, vamos montar a pasta que vai receber os arquivos do modelo.
Crie uma pasta chamada Template e, dentro dela, uma interface. No meu caso, comecei com o nome IRepository, mas você pode chamá-la como quiser.
No meu caso, vou montar a estrutura com o arquivo IServiceTemplate.cs, que é a interface do serviço. Ficou desta forma:
Exportando templates no Visual Studio
Logo após criar toda a estrutura, faça a exportação como template. Para isso, navegue até o menu Project > Export Template.
Segundo a documentação, se a opção não aparecer, você pode adicioná-la em Tools > Customize. Nesse caso, escolha a barra do menu Project e inclua o comando Export Template.
Escolhendo o tipo e o arquivo
Na primeira tela do assistente, selecione a opção Item Template. Em seguida, escolha o projeto que contém o arquivo e avance.
Na próxima tela, selecione a interface que acabamos de criar. Ela será a base do modelo exportado.
Referências, nome e ícone
Caso queira, selecione algumas dependências nessa etapa. Com isso, o arquivo gerado pelo template já vem com essas importações, como o System.Linq.
Depois, preencha o nome do seu template e a descrição dele. Essa descrição aparece do lado direito da janela Add New Item quando alguém escolhe o modelo.
Também existe a possibilidade de colocar um ícone customizado. Eu não vou colocar, pois não é obrigatório, mas você pode usar o logo da empresa ou do projeto ao qual o template se destina.
Por fim, clique em Finish.
O arquivo zip gerado
O Visual Studio abre uma pasta com o template compactado em um arquivo zip. Segundo a documentação, o local padrão é a pasta My Exported Templates, dentro de Documents\Visual Studio 2019.
Copie esse arquivo para outro diretório, onde seja possível abri-lo no VS Code ou em outro editor de sua preferência.
Extraia o conteúdo e abra a pasta no editor. Note que o assistente gerou três arquivos:
- O ícone, que será exibido no Visual Studio 2019.
- A classe de template, que neste caso é a interface.
- O arquivo de configuração
.vstemplate.
Editando o vstemplate para vários arquivos
Como o nosso template terá três arquivos de código, vamos editar manualmente o .vstemplate para aceitar os demais.
Esse arquivo é o que o Visual Studio lê para saber o que gerar. O arquivo padrão de configuração está desta forma:
Vamos editar para este modelo:
O código abaixo mostra uma versão equivalente, baseada no formato documentado pela Microsoft. Os nomes dos arquivos e as convenções podem variar conforme o padrão do seu projeto.
Vale notar que a documentação diz que o assistente gera os parâmetros sozinho quando o item já tem arquivos dependentes. Como os nossos templates no Visual Studio juntam arquivos independentes, a edição manual é necessária.
<VSTemplate Version="3.0.0" Type="Item"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<DefaultName>Service.cs</DefaultName>
<Name>ServiceTemplate</Name>
<Description>Creates the interface, request and implementation of a service</Description>
<ProjectType>CSharp</ProjectType>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<!-- Cada ProjectItem gera um arquivo no projeto -->
<ProjectItem ReplaceParameters="true" TargetFileName="I$fileinputname$Service.cs">IServiceTemplate.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="$fileinputname$Request.cs">ServiceTemplateRequest.cs</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="$fileinputname$Service.cs">ServiceTemplate.cs</ProjectItem>
</TemplateContent>
</VSTemplate>
A variável fileinputname
Note que existe uma variável chamada $fileinputname$. Ela corresponde ao nome do arquivo digitado na criação do item pelo Visual Studio 2019, sem a extensão.
Por isso, você pode definir padrões de nomes com prefixo e sufixo, tudo de acordo com o padrão do seu projeto. A documentação confirma que, nesse cenário, os nomes dos arquivos derivam do nome informado na janela Add New Item.
Além disso, o atributo ReplaceParameters="true" habilita a troca de parâmetros dentro do conteúdo dos arquivos. Sem ele, os templates no Visual Studio copiam o texto exatamente como está, inclusive com os marcadores.
Outros parâmetros reservados também ajudam bastante. Por exemplo, o $rootnamespace$ traz o namespace raiz do projeto somado à subpasta onde o item foi criado.
Criando os arquivos do template no Visual Studio
Com o vstemplate pronto, falta escrever o conteúdo dos arquivos que o template do Visual Studio vai copiar.
Logo após ajustar a configuração no VS Code, crie os métodos padrões da sua interface. No meu caso, criei um método chamado Execute, que recebe um request criado pelo próprio template.
namespace $rootnamespace$
{
// Contrato do serviço gerado pelo template
public interface I$fileinputname$Service
{
void Execute($fileinputname$Request request);
}
}
Em seguida, crie um arquivo chamado ServiceTemplateRequest.cs, ou com o nome que você desejar. Dentro dele, coloque o código da classe de request.
namespace $rootnamespace$
{
// Objeto enviado como parâmetro para o serviço
public class $fileinputname$Request
{
}
}
Essa classe será passada como parâmetro para o nosso método e para a nossa interface. Assim, cada serviço novo já nasce com o seu próprio objeto de entrada.
Na sequência, crie um arquivo chamado ServiceTemplate.cs, também com o nome que preferir. Dentro dele, faça a implementação da interface, conforme o exemplo abaixo.
using System;
namespace $rootnamespace$
{
// Implementação padrão do serviço gerado pelo template
public class $fileinputname$Service : I$fileinputname$Service
{
public void Execute($fileinputname$Request request)
{
throw new NotImplementedException();
}
}
}
Nesse caso, a classe implementa a interface junto com o método Execute que criamos anteriormente. Portanto, o desenvolvedor só precisa preencher a lógica de negócio.
Repare que os três arquivos usam os mesmos marcadores. Assim, quando o Visual Studio aplica o template, a interface, o request e a implementação ficam coerentes entre si.
Importando templates no Visual Studio
Depois de finalizar as configurações e as implementações, vamos importar o modelo dentro do Visual Studio 2019. Primeiramente, compacte esses arquivos em um zip, desta forma:
O seu arquivo zip deve conter somente os arquivos de template, conforme a imagem abaixo. Ou seja, nada de pastas extras na raiz do pacote.
Encontrando a pasta de item templates
Agora, dentro do Visual Studio 2019, navegue até Tools > Options.
Pesquise pela palavra Locations e entre no menu Projects and Solutions. Em seguida, copie o caminho presente no campo de localização dos item templates do usuário.
De acordo com a documentação, o caminho padrão é %USERPROFILE%\Documents\Visual Studio 2019\Templates\ItemTemplates. Abra esse caminho pela janela Executar, com a tecla Windows + R.
Copiando o zip para o Visual Studio
Caso já exista algum zip com o mesmo nome por causa da exportação anterior, exclua o arquivo existente. Depois, cole o zip que você acabou de gerar.
Se quiser manter os modelos organizados, mova o zip para a pasta Visual C# ou para a pasta da linguagem de sua preferência. Feito isso, feche o Visual Studio 2019, porque ele só carrega os modelos novos ao iniciar.
Testando o template no Visual Studio
Abra novamente o projeto console no Visual Studio.
Agora vamos testar o template. Crie uma nova pasta chamada TemplateTest, para que os arquivos gerados fiquem separados dentro dela.
Logo na sequência, vá até o menu Add > New Item.
Note que o template criado já aparece em primeiro lugar. Porém, caso ele não esteja ali, pesquise pelo nome na barra de pesquisa do lado direito.
Selecione o template e coloque o nome que desejar. Por exemplo, vou criar um serviço de CEP.
Note que não preciso colocar a extensão .cs nem o prefixo ou o sufixo do serviço. Afinal, o $fileinputname$ e as regras do vstemplate cuidam disso.
Pronto, a estrutura padrão de um serviço foi criada com sucesso. Agora basta implementar a sua lógica, sem se preocupar em copiar arquivos e estruturas de outros lugares.
Boas práticas com templates no Visual Studio
Primeiro, mantenha os arquivos-fonte dos modelos em um repositório. Dessa forma, toda a equipe consegue revisar e evoluir os templates no Visual Studio como qualquer outro código.
Em seguida, prefira parâmetros reservados a nomes fixos. Por exemplo, usar $rootnamespace$ evita namespaces errados quando o item é criado em subpastas.
Também vale lembrar que os parâmetros diferenciam maiúsculas de minúsculas. Então, $FileInputName$ não funciona no lugar de $fileinputname$.
Por fim, se a equipe usa a linha de comando, conheça também o dotnet new e outras formas de geração de código. O artigo sobre T4 templates no .NET mostra uma alternativa para gerar código a partir de modelos de texto.
Compartilhando templates no Visual Studio com a equipe
O jeito mais simples de compartilhar é distribuir o próprio zip. Então, cada pessoa copia o arquivo para a sua pasta de item templates e reinicia o IDE.
Para equipes maiores, a documentação do Visual Studio SDK descreve outro caminho. Nesse caso, os templates no Visual Studio podem ser empacotados em uma extensão VSIX, o que facilita o versionamento e a instalação.
Desde o Visual Studio 2017, porém, o IDE não procura mais templates customizados dentro das extensões por conta própria. Por isso, a extensão precisa fornecer arquivos de manifesto que indiquem onde os modelos estão instalados.
Além disso, um template do Visual Studio pode instalar pacotes NuGet junto com os arquivos. Esse recurso ajuda quando o serviço gerado depende de bibliotecas específicas.
Conclusão
Espero que tenha gostado desta dica. Acredito que os templates vieram para agregar em nossas vidas, para focarmos no que realmente importa, que é gerar valor para o nosso cliente ou negócio.
Com poucos passos, você exportou um item template, editou o vstemplate para vários arquivos e importou o resultado no Visual Studio 2019. Para se aprofundar, consulte a documentação oficial sobre como criar item templates.
Até a próxima!
FAQ
Qual a diferença entre item template e project template?
O item template adiciona arquivos a um projeto existente pela janela Add New Item. Já o project template cria um projeto inteiro a partir do zero.
Onde o Visual Studio guarda os item templates do usuário?
Por padrão, na pasta Documents\Visual Studio 2019\Templates\ItemTemplates. Você confirma o caminho em Tools > Options > Projects and Solutions > Locations.
Para que serve o parâmetro fileinputname?
Ele recebe o nome digitado na janela Add New Item, sem a extensão. Assim, você monta os nomes dos arquivos com prefixos e sufixos padronizados.
Por que o template não aparece na janela Add New Item?
Normalmente, o Visual Studio ainda não foi reiniciado ou o zip está na pasta errada. Também confira se os arquivos estão na raiz do zip.
Preciso usar o assistente Export Template?
Não é obrigatório, porque você pode escrever o vstemplate à mão. Mesmo assim, o assistente gera a base e economiza tempo.