すべてをスタートアップクラスに追加する以外に、ASP.NET Core 3.1で依存関係を登録するための堅牢な方法はありますか?


9

ASP.NET Core 3.1プロジェクトがあります。通常、クラスのConfigureServices()メソッドを使用して依存関係を登録しますStartup.cs

しかし、私は多くの依存関係を登録しなければならないことに気づき、ConfigureServices()見た目は巨大です!静的メソッドの拡張メソッドを作成してConfigureService() `クラスから呼び出すことができることはわかっていますが、もっと良い方法があるかどうか疑問に思っています。

このように1つずつ定義する必要なしにIoCコンテナに依存関係を登録する方法がある場合

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

回答:


10

関連する依存関係をカスタム拡張メソッドにグループ化することは、これを行う非常に一般的な方法です。ASP.NET Coreはすでに多くの内部サービスに対してこれを行っており、その上に簡単に拡張して、アプリケーションに必要な方法でそれらを設定できます。たとえば、認証と承認を設定するには:

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

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

    return services;
}

アプリケーション固有のサービスに対して同じことを行い、それらを別々の拡張メソッドに論理的にグループ化できます。

非常に類似したサービス登録が多数ある場合は、コンベンショナルベースの登録を採用することもできます(例:Scrutorを使用。たとえば、特定の名前空間内のすべてのサービスを、それぞれのインターフェースの一時的なものとして登録します。

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

Scrutorでは、サービスをスキャンするための非常に複雑なルールが許可されているため、サービスが特定のパターンに従っている場合は、そのためのルールを考え出すことができるでしょう。


3

カスタム属性(AutoBindAttributeと呼ばれる)を作成する

public class AutoBindAttribute : Attribute
{
}

以下のように使用します([AutroBind]で自動的にバインドするすべての実装を装飾します)

public interface IMyClass {}

[AutoBind]
public class MyClass : IMyClass {}

次に、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();
    }
}

それをStartup.csで呼び出します

public class Startup
{

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

}

注:ServiceCollectionExtentionsシングルトンなどのすべてのスコープをサポートするようにクラスを改善できます。この例は、一時的な存続期間のみを示しています。

楽しい!!!


0

言及されたものに加えて。

個人的には、各アセンブリごとに依存関係を登録する個別のクラスが必要です。これにより、適切なレイヤーでクラスを使用するためのより多くの制御が追加され、internalどのIMOが適切であるかをクラスに指定できます。

scanメカニズムを使用するかどうかはあなた次第です。一部のフレームワークは、デフォルトでこれを提供します。同様の依存関係を一連のクラス/メソッドにグループ化すると、変更に対する一貫した場所でロジックを解決し続けるのに役立ちます。両方のアプローチを組み合わせることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.