Более приятный способ внедрения вещей

· 2 мин чтения

Всякий раз, когда я создаю такие вещи, как сервисы, репозитории, атрибуты или что-то еще, чтобы внедрить их в свои приложения, мы должны сделать этот шаг, который фактически добавляет сервисы в приложение.

Это всегда одно и то же: вы переходите к Program.cs, затем в какой-то части файла добавляете builder.Services.AddScoped<MyService>(); для внедрения сервиса.

Что-то вроде этого:

[[[ТОК_2]]]

Я имею в виду, это работает, но я придирчив, и мне это не очень нравится.

Допустим, у нас есть несколько внедрений зависимостей, которые мы хотим сделать, и на самом деле это не одно и то же. В моем случае это может быть что-то вроде библиотеки, содержащей все репозитории, другой библиотеки, содержащей все сервисы, и, наконец, еще одной библиотеки, содержащей атрибуты.

В таком случае, можете ли вы представить себе, сколько строк нам придется добавить в Program.cs.

Допустим, у нас есть библиотека, содержащая некоторые сервисы. Если мы хотим включить все наши сервисы, нам придется работать с IServiceCollection.

Итак, мы собираемся создать static class с методом static под названием AddServices, который возвращает IServiceCollection.

В этом случае он будет называться IServiceCollectionServicesExtensions.

/// <summary>
/// IServiceCollectionServicesExtensions class
/// </summary>
public static class IServiceCollectionServicesExtensions
{
    /// <summary>
    /// AddCoreServices
    /// </summary>
    /// <param cref="IServiceCollection" name="services">Parameter for <see cref="IServiceCollection"/></param>
    /// <returns>An object of type <see cref="IServiceCollection"/></returns>
    public static IServiceCollection AddServices(this IServiceCollection services)
    {
        services
            .AddScoped<AService>()
            .AddScoped<BService>()
            .AddScoped<CService>()
            .AddScoped<DService>();

        return services;
    }
}

Мало того, у нас также есть еще одна библиотека, включающая несколько репозиториев, используемых этими сервисами, поэтому давайте сделаем то же самое.

[[[ТОК_11]]]

Теперь у нас есть репозитории и методы сервисов для внедрения, но как их использовать?

Давайте вернемся к нашему Program.cs и добавим следующее:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

// Repositories
builder.Services.AddRepositories(); // 👀

// Services
builder.Services.AddServices(); // 👀

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Это выглядит намного чище, не так ли? Итак, мы успешно внедрили некоторые сервисы и репозитории, но теперь это выглядит лучше, и у нас действительно есть то, что мы внедрили, во внешней библиотеке.