web-dev-qa-db-ja.com

ASP.NETコア依存性注入を使用してデコレータを適用する方法

ASP.NET MVC 5アプリケーションでは、次のStructureMap構成があります。

cfg.For(typeof(IRequestHandler<,>)).DecorateAllWith(typeof(MediatorPipeline<,>));

ASP.NET Core IOCでこの構成を行う方法を知っている人はいますか?

19
Miguel Moura

すぐに使用できるIoCコンテナは、デコレーションパターンや自動検出をサポートしていません。これは、私が知る限り「設計による」ものです。

アイデアは、箱から出してすぐに機能する、または他のIoCコンテナをプラグインしてデフォルトの機能を拡張できる基本的なIoC構造を提供することです。

したがって、高度な機能(特定のコンストラクターのサポート、インターフェイスを実装するすべてのタイプの自動登録、またはデコレーターとインターセプターの挿入)が必要な場合は、自分で作成するか、この機能を提供するIoCコンテナーを使用する必要があります。

14
Tseng

この 回避策 は、タイプのすべてのインスタンスにデコレータを適用するわけではありませんが、拡張メソッドを使用してデコレータロジックを別のファイルに抽象化します。

次のようなデコレータ構造の定義:

public static class QueryHandlerRegistration
{
    public static IServiceCollection RegisterQueryHandler<TQueryHandler, TQuery, TResult>(
        this IServiceCollection services) 
        where TQuery : IQuery<TResult>
        where TQueryHandler : class, IQueryHandler<TQuery, TResult>
    {
        services.AddTransient<TQueryHandler>();
        services.AddTransient<IQueryHandler<TQuery, TResult>>(x =>
            new LoggingDecorator<TQuery, TResult>(x.GetService<ILogger<TQuery>>(), x.GetService<TQueryHandler>()));
        return services;
    }
}

そしてそれを次のように呼びます:

services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();

services.RegisterQueryHandler<FindThingByIdQueryHandler, FindThingByIdQuery, Thing>();

Scrutor パッケージが作業中です。

3
Willie

私の blogpost では、比較的単純な拡張メソッドでこの問題を簡単に解決する方法について説明しました。これは、デコレータ構成がどのように見えるかを示すその投稿の例です。

services.AddDecorator<IEmailMessageSender, EmailMessageSenderWithRetryDecorator>(decorateeServices =>
    {
        decorateeServices.AddScoped<IEmailMessageSender, SmtpEmailMessageSender>();
    });
0
sich