Una forma más agradable de inyectar cosas.

· 3 min de lectura

Siempre que estoy creando cosas como servicios, repositorios, atributos o lo que sea para inyectar en mis aplicaciones, hay un paso que debemos realizar, que en realidad es agregar los servicios a la aplicación.

Esto es siempre lo mismo, vas a Program.cs, luego procedes a agregar en alguna parte del archivo builder.Services.AddScoped<MyService>(); para inyectar el servicio.

Algo como esto:

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

Quiero decir, funciona, pero soy exigente y realmente no me gusta.

Digamos que tenemos múltiples inyecciones de dependencia que queremos hacer, y en realidad no son lo mismo, en mi caso esto podría ser algo así como tener una biblioteca que contenga todos los repositorios, otra biblioteca que tenga todos los servicios y, por último, otra biblioteca que contenga atributos.

En ese caso, ¿te imaginas la cantidad de líneas que tenemos que agregar a Program.cs.

Digamos que tenemos una biblioteca que contiene algunos servicios, si queremos incluir todos nuestros servicios, tenemos que trabajar con IServiceCollection.

Entonces vamos a crear un static class que tendrá un método static llamado AddServices que devuelve un IServiceCollection.

En este caso, se llamará 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;
    }
}

No solo eso, también tenemos otra biblioteca que incluye algunos repositorios que utilizan estos servicios, así que hagamos lo mismo.

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

Ahora, tenemos nuestros repositorios y métodos de servicios para inyectar creados, pero ¿cómo los usamos?

Volvamos a nuestro Program.cs y agreguemos lo siguiente:

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

Esto parece mucho más limpio, ¿no? Bueno, con eso, hemos inyectado con éxito algunos servicios y repositorios, pero ahora se ve mejor y en realidad tenemos lo que inyectamos en la biblioteca externa.