Apakah ada cara yang kuat untuk mendaftarkan dependensi di ASP.NET Core 3.1 selain menambahkan semuanya ke dalam kelas Startup?

9

Saya memiliki proyek ASP.NET Core 3.1. Biasanya, saya mendaftarkan dependensi menggunakan ConfigureServices()metode di Startup.cskelas.

Tapi, saya mendapati diri saya harus mendaftarkan banyak dependensi dan ConfigureServices()terlihat besar! Saya tahu saya mungkin dapat membuat metode ekstensi metode statis dan memanggilnya dari kelas ConfigureService (), tetapi bertanya-tanya apakah ada cara yang lebih baik.

Jika ada cara untuk mendaftarkan dependensi dalam wadah IoC tanpa harus mendefinisikannya satu per satu seperti ini

services.AddScoped<Interface, Class>();
.... 200 lines later
services.AddScoped<ISettings, Settings>()

sumber

Jawaban:

10

Mengelompokkan dependensi terkait ke dalam metode ekstensi khusus adalah cara yang sangat umum untuk melakukan ini. ASP.NET Core sudah melakukan ini untuk banyak layanan internal, dan Anda dapat dengan mudah mengembangkannya dan mengaturnya sesuai kebutuhan untuk aplikasi Anda. Misalnya untuk mengatur otentikasi dan otorisasi:

public IServiceCollection AddSecurity(this IServiceCollection services)
{
    services.AddAuthentication()
        .AddCookie();

    service.AddAuthorization(options =>
    {
        options.DefaultPolicy = …;
    });

    return services;
}

Anda dapat melakukan hal yang sama untuk layanan khusus aplikasi Anda dan mengelompokkannya secara logis dalam metode ekstensi yang terpisah.

Jika Anda memiliki banyak pendaftaran layanan yang sangat mirip, Anda juga dapat menggunakan registrasi berbasis konvensi misalnya menggunakan Scrutor . Sebagai contoh, ini mendaftarkan semua layanan dalam namespace tertentu sebagai sementara untuk antarmuka masing-masing:

services.Scan(scan => scan
    .FromAssemblyOf<Startup>()
        .AddClasses(c => c.InNamespaces("MyApp.Services"))
            .AsImplementedInterfaces()
            .WithTransientLifetime()
);

Scrutor memungkinkan aturan yang sangat kompleks untuk memindai layanan, jadi jika layanan Anda mengikuti beberapa pola, Anda mungkin akan dapat membuat aturan untuk itu.

menyodok
sumber
3

Buat atribut khusus (disebut AutoBindAttribute)

public class AutoBindAttribute : Attribute
{
}

Gunakan seperti di bawah ini (Hiasi semua implementasi yang ingin Anda ikat secara otomatis dengan [AutroBind])

public interface IMyClass {}

[AutoBind]
public class MyClass : IMyClass {}

Sekarang buat metode extention untuk IServiceCollection

public class ServiceCollectionExtentions
{
    public static void AutoBind(this IServiceCollection source, params Assembly[] assemblies)
    {
       source.Scan(scan => scan.FromAssemblies(assemblies)
        .AddClasses(classes => classes.WithAttribute<AutoBindAttribute>())
        .AsImplementedInterfaces()
        .WithTransientLifetime();
    }
}

Sekarang panggil di Startup.cs

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AutoBind(typeof(Startup).Assembly);
    }

}

Catatan: Anda dapat meningkatkan ServiceCollectionExtentionskelas untuk mendukung semua lingkup seperti singleton, dll. Contoh ini hanya menunjukkan untuk masa hidup sementara.

Nikmati!!!

Dilhan Jayathilake
sumber
0

Selain apa yang disebutkan.

Secara pribadi saya suka memiliki dependensi pendaftaran kelas yang terpisah per setiap perakitan. Ini menambahkan lebih banyak kontrol dalam menggunakan kelas di lapisan kanan dan memungkinkan untuk membuat mereka internalyang IMO bagus.

Apakah menggunakan scanmekanisme atau tidak, itu terserah Anda. Beberapa kerangka kerja memberikan ini secara default. Pengelompokan dependensi yang sama dalam satu set kelas / metode, pada gilirannya, akan membantu menjaga penyelesaian logika di tempat yang konsisten untuk setiap perubahan. Anda dapat menggabungkan kedua pendekatan tersebut.

Shymep
sumber