Há poucos dias, trabalhando em um cliente na CWI surgiu a necessidade de fazer a criação de vários novos serviços. Precisávamos que estes serviços já fossem criados com alguns padrões de código e que estes padrões iniciais ficassem flexíveis para alteração do desenvolvedor que estivesse criando o projeto.
Inicialmente, discutimos a alternativa mais simples pra nós: ter um repositório de template para ser clonado e editado pelo desenvolvedor que está criando o novo projeto. Apesar de ser uma alternativa boa e efetiva (nas versões modernas do .NET) achamos que faria mais sentido termos templates para serem usados diretamente com a CLI do .NET (dotnet new). Dessa forma podemos distribuir um conjunto de templates úteis, não só de projetos, mas de itens criados frequentemente, para facilitar o dia a dia da equipe.
Neste post conto a experiência de como fizemos a criação de um template para a CLI do .NET.
Código do template
Primeiro, é necessário criar um novo projeto para conter o código do template. Isso pode ser feito de qualquer forma que se use para criar um projeto, eu costumo usar o CLI para isso, mas qualquer forma é válida.
| |
Depois é só adicionar o código necessário do template. Neste projeto precisávamos seguir alguns padrões bem definidos: injetar alguns serviços, configurar o pipeline do ASP.NET Core com alguns middlewares e criar arquivos web.config e appSettings.json com configurações padrões.
Além disso, era necessário passar um argumento para um dos métodos chamados na classe Program e este argumento, idealmente, deveria ser definido no nomento de executar o dotnet new.
Pra fins de entendimento, o código do arquivo Program.cs ficou desta forma:
| |
A linha .AddServicesWithParam(ParamDoServico); é especialmente importante aqui, porque queremos substituir este parâmetro pelo valor informado no momento da execução do dotnet new.
Configurando o template
Com o código pronto, é hora de fazer a configuração do template.
Para isso é necessário criar uma pasta chamada .template.config esta pasta deve estar um nível acima do arquivo .csproj. A nossa estrutura de pastas ficou assim:
| |
💡 O schema completo deste arquivo pode ser visto no JSON Schema Store.
O nosso template.json ficou parecido com este.
| |
Este JSON é basicamente autoexplicativo, mas é importante prestar atenção em dois detalhes:
- A propriedade
sourceNamedefine um valor que será substituído em todos os arquivos pelo valor informado no argumento--namecaso não haja alguma configuração para ignorar algum arquivo - A propriedade
symbolconfigura um novo parâmetro para odotnet new. Neste caso, estamos configurando um parâmetro chamadoParamServicoque é do tipo texto e que seu valor substituirá a chaveParamDoServicono código, além disso é configurado um valor padrão caso este argumento não seja informado.
Testando o template
Agora o template está pronto e configurado pra ser usado. A CLI do .NET permite fazer a instalação de templates pelo sistema de arquivos mesmo e, para testar, é necessário executar a instalação e executar um dotnet new.
Instalação
| |
A saída deve ser algo parecido com a abaixo.
| |
Usando com dotnet new 🚀
Agora é só usar o template para criar novos projetos.
| |
Como esperado, nosso novo projeto foi criado com base no código do template. Note os namespaces ficaram certos (graças ao parâmetro sourceName) e o valor ParamDoServico foi substituído por XptoAbcd.
Empacotando
Depois de termos um template funcional, precisamos encontrar uma forma de compartilhar com nossos colegas. Compartilhar num sistema de arquivos acessível a todos os membros da equipe é uma opção válida, mas não é muito boa no nosso caso onde todo mundo trabalha remotamente e usamos VPN apenas para atividades específicas. A forma que achamos ideal foi compartilhar o template no nosso feed Nuget.
Pra fazer isso criamos um pacote nuget com todos os templates e fizemos o deploy deste pacote no feed acessível por toda a equipe.
Primeiro, criamos um novo projeto C# simples para facilitar a criação do csproj.
| |
O arquivo Program.cs pode ser removido e o conteúdo do arquivo .csproj deve ficar parecido com o abaixo.
| |
O conteúdo deste arquivo foi baseado no exemplo da documentação.
O primeiro bloco define propriedades usadas na geração do pacote Nuget.
O segundo bloco inclui configurações relacionadas à configuração do projeto para incluir os templates na pasta apropriada no pacote NuGet quando ele é criado.
O terceiro bloco (em ItemGroup) define os itens que devem ser adicionados ou removidos no pacote gerado e que não deve haver compilação dos arquivos de código.
Depois disso, é possível empacotar os templates e distribui-lo em algum feed Nuget.
| |
E a instalação pode ser feita pelo identificador do pacote.
| |
