Tworzenie własnego szablonu dla projektu .NET Core

Ostatnio w pracy rozpoczęliśmy nowy projekt, który oparty jest na mikroserwisach. Cały proces tworzenia aplikacji zaczęliśmy od stworzenia dedykowanego repozytorium dla każdej usługi (o tym podejściu pisałem tutaj) i umieszczeniu w nim projektu ASP.NET Core, który następnie należało odpowiednio przygotować. Mam tu na myśli np. stworzenie poprawnej struktury katalogów, dodanie podstawowej integracji z istniejącą infrastrukturą itd. tak, aby każda usługa była możliwie podobna pod względem organizacji plików i ich nazewnictwa. Cała praca nie była więc zbyt pasjonująca, ponieważ w głównej mierze sprowadzało się to do kopiuj-wklej i zmiany namespaców. Ja jednak jako jednostka ponadprzeciętnie leniwa zacząłem zastanawiać się czy twórcy platformy .NET Core nie przewidzieli tego typu scenariuszy i nie zostawili nam do dyspozycji narzędzi, aby cały proces częściowo zautomatyzować. Po stosunkowo krótkim poszukiwaniu odpowiedzi, okazało się, że moje przypuszczenia się potwierdziły.

 

Przykładowa aplikacja ASP.NET Core

Załóżmy, że chciałbyś/chciałabyś stworzyć szablon na podstawie bardzo prostej aplikacji ASP.NET Core (poniższy został wygenerowany poleceniem dotnet new webapi -n AspNetCustom) . Struktura tego projektu przedstawia się następująco:

 

 

Widać tu dwie modyfikacje względem domyślnie wygenerowanego projektu:

  • Katalog Controllers nie zawiera ValuesController, a BaseController
  • Pojawił się nowy katalog o nazwie Providers, który zawiera interfejs ICustomProvider wraz z jego implementacją

Sam kod jest również lekko zmodyfikowany. Poniżej implementacja BaseController:

 

    [Route("api/[controller]")]
    [ApiController]
    public abstract class BaseController : ControllerBase
    {
        protected readonly ILogger Logger;

        protected BaseController(ILogger logger)
            => Logger = logger;
    }

 

Następnie provider:

 


public interface ICustomProvider
{
}



public class CustomProvider : ICustomProvider
{
}

 

Ostatnie modyfikacje znajdują się w klasie Startup wzbogaconej o dodanie CORS oraz rejestrację providera:

 


    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddCors(options =>
                options.AddPolicy("CustomPolicy", builder =>
                    builder
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowAnyOrigin()));

            services.AddTransient<ICustomProvider, CustomProvider>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseCors("CustomPolicy");
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

 

Aplikacja de facto nic nie robi, ale to w tym przypadku nie ma najmniejszego znaczenia. Istotnie jest to, że posiadamy projekt z własną strukturą plików, a część z nich jest dodatkowo zmodyfikowana względem domyślnych implementacji. Przejdźmy do właściwej części wpisu.

 

Generowanie szablonu na podstawie projektu .NET Core

Aby na podstawie projektu stworzyć szablon, w pierwszej kolejności stwórz katalog o nazwie .template.config i umieść go w katalogu głównym projektu (na poziomie pliku *.csproj). Następnie w środku nowo utworzonego folderu dodaj plik o nazwie template.json. Całość powinna wyglądać w ten sposób:

 

 

W środku pliku template.json umieść poniższy kod:

 


{
    "author": "Dariusz Pawlukiewicz",
    "classifications": [ "Web", "MVC", "CORS" ],
    "identity": "ASP.NET.Core.Custom.Cors",
    "name": "ASP.NET Core Custom app",
    "shortName": "aspnetcustom",
    "tags": {
      "language": "C#"
    },
    "sourceName": "AspNetCustom",
    "preferNameDirectory" : "true"
  }
  

 

Kolejne parametry to:

  • author – autor szablonu
  • classifications – tagi, po których użytkownik będzie mógł łatwiej wyszukać ten szablon
  • identity – unikalna nazwa dla szblonu
  • name – nazwa szablonu, którą użytkownik zobaczy w dotnet CLI
  • shortName – skrócona nazwa szablonu, która zostanie użyta jako parametr dla polecania dotnet new
  • tags/language – oznaczenie dla jakiego języka przeznaczony jest szablon
  • sourceName – domyślna baza dla namespaców. Zostanie podmieniona po podaniu parametru -n w poleceniu dotnet new
  • preferNameDirectory – utworzy katalog z nazwą projektu

Oczywiście w swoim projekcie wszystkie z powyższych parametrów odpowiednio zmodyfikuj 😉

Kiedy ten etap masz już za sobą zapisz plik, a następnie otwórz konsolę i przejdź w niej do katalogu głównego projektu. Jeżeli po wywołaniu polecanie dir (na WIN) lub ls (na UNIX) nie zobaczysz katalogu .template.config,  nie martw się 😉 Teraz pozostaje Ci tylko wykonać polecenie:

 


dotnet new -i .

 

Po krótkiej chwili Twój szablon powinien pojawić się liście dostępnych:

 

 

Jeżeli w przyszłości szablon nie będzie Ci już potrzebny to konsolą znów ustaw się w katalogu głównym projektu, a następnie wywołaj polecenie:

 


dotnet new -u .

 

Zobaczmy zatem jak działa nasz szablon. Na jego podstawie stworzę nowy projekt o nazwie MyAwesomeAspNetCoreApp. W tym celu wykonam polecenie:

 


dotnet new aspnetcustom -n MyAwesomeAspNetApp

 

W rezultacie we wskazanym miejscu powinien zostać utworzony katalog o nazwie MyAwesomeAspNetCoreApp zawierający projekt o odpowiedniej strukturze:

 

 

Warto zaznaczyć, że dotnet CLI umożliwia także umieszczanie i późniejsze referowanie do szablonów umieszczonych w paczkach NuGet. Więcej szczegółów na ten temat znajdziesz w oficjalnej dokumentacji.

 

  • Pingback: dotnetomaniak.pl()

  • Polak

    Nie wiesz może czy jest możliwość wykorzystania tego z projektami w .net framework? I czy można utworzyć szablon zawierający wiele projektów?