2

Ninjectで、実行時にすべてを指定せずに、ジェネリックインターフェイスを実装する特定のアセンブリ内のすべてのタイプのバインディングを作成する必要があります。Autofacでオープンジェネリックがどのように機能するかのようなものです。

これは私が思いついたものです...

kernel.Bind(x => x.FromThisAssembly()
    .SelectAllClasses()
    .Where(t => t.IsAssignableFrom(
        typeof(ICommandHandler<>)))
        .BindAllInterfaces());

以下のメソッドを呼び出すと、すべてのタイプの配列が実装されICommandHandler<T>ていると思いますが、何も生成されません...

public void Process<TCommand>(TCommand command) 
    where TCommand : ICommand
{
    var handlers = 
        _kernel.GetAll<ICommandHandler<TCommand>>();

    foreach(var handler in handlers)
    {
        handler.Handle(command);
    }
}

これを達成するための既存の方法はありますか?または、コンベンションAPIを使用して自分でロールする必要がありますか?

それはかなり一般的なパターンのようで、私自身の実装を書かなくてもこれを達成できるかどうか疑問に思っていました。

4

1 に答える 1

6

2つの問題があるため、バインディングはまったく何もしていません。

  1. IsAssignableFromは、逆の順序でパラメーターを予期します。指定しました

    SomeCommand x = new ICommand<>();
    
  2. 閉じたジェネリッククラスは、開いたジェネリック型に割り当てることはできません。または言い換えれば

    ICommand<> x = new SomeCommand(); 
    

    は有効なコードではありません。

あなたが欲しいものは:

kernel.Bind(x => x.FromThisAssembly()
                  .SelectAllClasses().InheritedFrom(typeof(ICommandHandler<>))
                  .BindAllInterfaces());
于 2012-07-30T08:32:56.650 に答える