1
  1. 単純なインターフェースを想定します。

    public interface ICommandHandler<T>
    {
        void Handle(T command);
    }
    
  2. T次のような異なる具象のいくつかの実装を想定します。

    public class FooCommandHandler : ICommandHandler<FooCommand> { /*...*/ }
    
  3. そのインターフェイスの一般的なファクトリ実装を想定します。

    public class FactoryCommandHandler<T> : ICommandHandler<T>
    {
        public FactoryCommandHandler(Func<ICommandHandler<T>> factory) { /*...*/ }
        /*...*/
    }
    

ここで、が解決されたときに解決されるインスタンスになるように、3からのファクトリ ハンドラーを登録しますICommandHandler<T>
私の問題は、他の実装を正しく登録できないため、それらのファクトリを解決できないことです。

これが私が試したものです:

builder.RegisterAssemblyTypes(assembly)
       .Where(type => type.Name.EndsWith("CommandHandler"))
       .Named("concreteCommandHandler", typeof(ICommandHandler<>));


builder.RegisterGeneric(typeof(FactoryCommandHandler<>)
       .WithParameter(
             (p, c) => true,
             (p, c) => c.ResolveNamed("concreteCommandHandler", p.ParameterType))
       .As(typeof(ICommandHandler<>));

Func<ICommandHandler<SomeConcreteCommand>>ただし、名前が登録されていないため、これは失敗します。この場合、Autofac は通常サポートしているファクトリを自動的に作成できないようです。

登録を修正して目標を達成するにはどうすればよいですか?

4

3 に答える 3

1

ここでSimple Injectorをプラグインして申し訳ありませんが、Simple Injector の子供の遊びで苦労していることに気付かずにはいられませんでした。Simple Injector では、2 行のコードで必要なことを行うことができます。

// using SimpleInjector;
// using SimpleInjector.Extensions;

var container = new Container();

container.RegisterManyForOpenGeneric(
    typeof(ICommandHandler<>), 
    assembly);

container.RegisterSingleDecorator(
    typeof(ICommandHandler<>), 
    typeof(FactoryCommandHandler<>));

これらの 2 つの単純な行は、次のことを保証します。

  • 提供されたアセンブリは、 の具体的な実装のために検索されICommandHandler<T>ます。
  • 具体的な実装でICommandHandler<T>インターフェイスが複数回定義されている場合は、そのインターフェイスのクローズド ジェネリック バージョンごとに登録されます。
  • は、実装FactoryCommandHandler<T>をラップするように登録されていICommandHandler<T>ます。ICommandHandler<T>そのジェネリックの単一インスタンスのクローズド ジェネリック バージョンごとFactoryCommandHandler<T>に返されます。
  • デコレート (ラップされたインスタンス) を作成できるようFunc<ICommandHandler<T>>に が注入されます。FactoryCommandHandler<T>これにより、そのインスタンスの作成が実質的に遅延します。
  • 注入された工場は装飾者の生活を守ります。

のみがシングルトンであるFactoryCommandHandler<T>a に依存します。Func<T>したがってFactoryCommandHandler<T>、それ自体をシングルトンとして登録できます (上記の登録で何が起こるか)。他のライフスタイルの依存関係に依存する場合は、一時的に登録した方がよいかもしれません。

于 2013-06-12T19:43:54.543 に答える