3

ハンドラーがコンテナーを介して登録される多態的なイベントの集約/処理にUnityを使用したいと思います。

ハンドラーは、入力パラメーターとしてのみ使用されるため、「in」修飾子を使用してジェネリックパラメーターを宣言します。したがって、パラメーターは反変です。

次のサンプルを検討します。

interface IHandler<in T> { void Handle(T message); }

interface IMsg { string Message { get; } }

class MsgA : IMsg { ... }

class MsgB : IMsg { ... }

class MsgAHandler : IHandler<MsgA> {
  public void Handle(MsgA msg) { ... }
}

class MsgBHandler : IHandler<MsgB> {
  public void Handle(MsgB msg) { ... }
}

class MsgHandler : IHandler<IMsg> {
  public void Handle(IMsg msg) { ... }
}

class ObjectHandler : IHandler<object> {
  public void Handle(object msg) { ... }
}

class Events {
   public void Publish<T>(T message) {
     // Actually this code is more complex for Unity, because it first tries to
     // resolve the default registered component using .Resolve(),
     // then use .ResolveAll() to resolve all named components
     foreach (var handler in this.container.ResolveAll<IHandle<T>>()) {
       handler.Handle(message);
     }
   }
}

私の期待は次のとおりです。

  • を受け取ったら、、、にMsgAディスパッチする必要がMsgAHandlerありMsgHandlerますObjectHandler
  • を受け取ったらIMsg、とに発送する必要がMsgHandlerありObjectHandlerます。
  • ObjectHandlerすべてのメッセージを受信する必要があります。

デフォルトでは、Castle Windsorは、特定の構成なしでこのシナリオを正しく処理します(v2.5.1でテスト済み)。

Unityは、解像度を向上させ、Resolve<IHandle<MsgA>>()実装している任意のタイプに一致させる方法を公開していますIHandle<IMsg>IHandle<object>

UnityExtensions(ルールやポリシーのマッチングなど)を使用してサンプルを探しましたが、成功しませんでした。

誰かがそのようなシナリオを実装するために使用する正しいメカニズムに私を導くことができますか?

4

1 に答える 1

1

あなたはできますか:

container.RegisterType(typeof(IHandle<>), typeof(MsgAHandler<>))

ただし、それが正しく機能するためには、おそらくコードの一部を変更する必要があります。お気に入り:

public interface IHandler<in THandler> where THandler : class, IMsg
{ void Handle(THandler message); }
于 2011-06-03T17:54:48.093 に答える