1

IQueryHandler<TQUery,TResult>MVC コントローラーに注入します。これらすべてをコンテナにグローバルに登録します

の結果をキャッシュできるデコレータを作成しましたIQueryHandler

キャッシュされた結果を取得したい場合もあれば、同じハンドラーから取得したくない場合もあります。

コンストラクターパラメーターの名前に基づいて、条件付きで装飾されたハンドラーを取得することは可能ですか? たとえばIQueryHandler<UnemployedQuery, IEnumerable<People>> cachedPeopleHandler、コンストラクターのパラメーター名の前に cached を付けると、実際にはデコレーターでラップされますか?

物事を単純化するために、構成アプローチよりも慣例を使用しようとしています。

4

1 に答える 1

2

はい、可能です。以下は、それを達成する方法に関する簡単な実例です。

class Program
{
    public interface IQueryHandler{}

    private class QueryHandler : IQueryHandler
    {
    }

    private class CacheQueryHandler : IQueryHandler
    {
    }

    public interface IService
    {
    }

    private class Service : IService
    {
        private readonly IQueryHandler _queryHandler;
        private readonly IQueryHandler _cacheQueryHandler;

        public Service(IQueryHandler queryHandler, IQueryHandler cacheQueryHandler)
        {
            _queryHandler = queryHandler;
            _cacheQueryHandler = cacheQueryHandler;
        }

        public override string ToString()
        {
            return string.Format("_queryHandler is {0}; _cacheQueryHandler is {1}", _queryHandler,
                _cacheQueryHandler);
        }
    }

    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        // Register the dependency
        builder.RegisterType<QueryHandler>().As<IQueryHandler>();
        // Register the decorator of the dependency
        builder.RegisterType<CacheQueryHandler>().Keyed<IQueryHandler>("cache");

        // Register the service implementation
        builder.RegisterType<Service>().AsSelf();

        // Register the interface of the service
        builder.Register(c =>
        {
            var ctor = typeof (Service).GetConstructors()[0];

            var parameters =
                ctor.GetParameters()
                    .Where(p => p.Name.StartsWith("cache"))
                    .Select(p => new NamedParameter(p.Name, c.ResolveKeyed("cache", p.ParameterType)));

            return c.Resolve<Service>(parameters);
        }).As<IService>();

        using (var container = builder.Build())
        {
            var service = container.Resolve<IService>();
            Console.WriteLine(service.ToString());

            Console.ReadKey();
        }

    }
}

更新:
基本的に、次のことを行う必要があります
。 1. 一般的な規則を考えます。あなたの場合、ctorパラメータ名のプレフィックス「キャッシュ」。
2. 通常どおり依存関係を登録します。
3. デコレーターを登録して、元の依存関係を上書きしないようにし、規則に基づいて簡単に解決できるようにします。例: Keyed、Named、via Attribute など。
4. デコレータを使用するクラスの実際の実装を
登録します。

注: 簡単で実用的な例を提供しました。それを素晴らしく、使いやすく、高速にするのはあなたの責任です。たとえば、拡張機能、汎用、キャッシュ リフレクションの結果などとして作成します。とにかく難しいことではありません。
ありがとう。

于 2013-09-27T17:09:42.077 に答える