何かを注入するためのより良い方法

· 2分で読める

サービス、リポジトリ、属性など、アプリケーションに挿入するものを構築するときは常に、実際にアプリケーションにサービスを追加する必要があるステップがあります。

これは常に同じです。Program.cs に移動し、サービスを挿入するためにファイルの一部に builder.Services.AddScoped<MyService>(); を追加します。

次のようなもの:

var builder = WebApplication.CreateBuilder(args);

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

// Repositories
builder.Services.AddScoped<ARepository>(); // 👀
builder.Services.AddScoped<BRepository>(); // 👀

// Services
builder.Services.AddScoped<AService>(); // 👀
builder.Services.AddScoped<BService>(); // 👀
builder.Services.AddScoped<CService>(); // 👀
builder.Services.AddScoped<DService>(); // 👀

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();

つまり、それは機能しますが、私は好き嫌いがあり、あまり好きではありません。

実行したい依存関係の注入が複数あるとします。それらは実際には同じものではありません。私の場合、これは、すべてのリポジトリを含むライブラリ、すべてのサービスを含む別のライブラリ、そして最後に属性を含む別のライブラリを持つようなものになる可能性があります。

その場合、Program.cs に追加しなければならない行の量を想像できますか。

いくつかのサービスを含むライブラリがあるとします。すべてのサービスを含めたい場合は、IServiceCollection を操作する必要があります。

そこで、IServiceCollection を返す AddServices という static メソッドを持つ static class を作成します。

この場合、名前は 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;
    }
}

それだけでなく、このサービスで使用されているいくつかのリポジトリを含む別のライブラリもあるので、同じようにしましょう。

/// <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 AddRepositories(this IServiceCollection services)
    {
        services
            .AddScoped<ARepository>()
            .AddScoped<BRepository>();

        return services;
    }
}

これで、注入するリポジトリとサービス メソッドが作成されましたが、それらはどのように使用するのでしょうか?

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();

これでかなりすっきりしましたね。これで、いくつかのサービスとリポジトリを正常に挿入できましたが、見た目はさらに良くなり、実際に外部ライブラリに注入したものが得られました。