Eine schönere Art, Dinge zu injizieren

· 3 Min. Lesezeit

Immer wenn ich Dinge wie Dienste, Repositorys, Attribute oder was auch immer erstelle, um sie in meine Anwendungen einzufügen, müssen wir diesen Schritt ausführen, nämlich das eigentliche Hinzufügen der Dienste zur Anwendung.

Dies ist immer das Gleiche: Sie gehen zu Program.cs und fügen dann an einem Teil der Datei builder.Services.AddScoped<MyService>(); hinzu, um den Dienst einzubinden.

Etwas in der Art:

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

Ich meine, es funktioniert, aber ich bin wählerisch und mag es nicht wirklich.

Nehmen wir an, wir möchten mehrere Abhängigkeitsinjektionen durchführen, und es handelt sich nicht wirklich um dasselbe. In meinem Fall könnte dies etwa eine Bibliothek sein, die alle Repositorys enthält, eine andere Bibliothek, die alle Dienste enthält, und schließlich eine weitere Bibliothek, die Attribute enthält.

Können Sie sich in diesem Fall vorstellen, wie viele Zeilen wir zu Program.cs hinzufügen müssen?

Nehmen wir an, wir haben eine Bibliothek, die einige Dienste enthält. Wenn wir alle unsere Dienste einschließen möchten, müssen wir mit IServiceCollection arbeiten.

Wir erstellen also ein static class mit einer static-Methode namens AddServices, die ein IServiceCollection zurückgibt.

In diesem Fall erhält es den Namen 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;
    }
}

Darüber hinaus verfügen wir über eine weitere Bibliothek, die einige Repositorys enthält, die von diesen Diensten verwendet werden. Machen wir also dasselbe.

/// <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;
    }
}

Jetzt haben wir unsere Repositorys und Dienstmethoden zum Injizieren erstellt, aber wie verwenden wir sie?

Kehren wir zu unserem Program.cs zurück und fügen wir Folgendes hinzu:

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

Das sieht viel sauberer aus, nicht wahr? Damit haben wir einige Dienste und Repositories erfolgreich eingefügt, aber jetzt sieht es besser aus und wir haben das, was wir einspeisen, tatsächlich in der externen Bibliothek.