2

Rebusで初心者が始めたときに問題がいくつかあります。Rebus ReadMeファイルのすべての優れたサンプルはWindsorCastleを使用していますが、そのオプションはありません。代わりにUnityを使用する必要があります。

私の最初の課題は、例に示されているように、UnityIoCコンテナに適したアダプタを見つけることでした。

var someContainerAdapter =
    new AdapterForMyFavoriteIocContainer(myFavoriteIocContainer);

私はついに仕事をしているように見えるいくつかのコードをここで見つけましたが、 IContainerAdapterインターフェイスを自分で実装する必要があるため、おそらくより良いコンテナが存在します(それが必要かどうか疑問に思います...)。

しかし、私はそれと一緒に暮らすことができます...

私の次の問題はもっとひどいです、そして私はまだ知りません。Rebus Getting Started-exampleでは、以下を使用してIoCコンテナーにハンドラーを追加します。

container.Register(
    Component.For<IHandleMessages<DateTime>>()
    .ImplementedBy<PrintDateTime>());

上記はWindsorCastleの構文であり、同じアクションに対してUnityの構文がどのようになるべきかわかりません。だから私はここでいくつかの助けが必要です。Unityで動作する小さなソリューションへの参照を取得できるかどうかを提案します。

4

3 に答える 3

5

私の提案はRebus.Unity、Rebus用のすぐに使えるUnityコンテナアダプターであるを使用することです。これは、素晴らしいRebus寄稿者の1人によって作成されました。

そのためのNuGetパッケージがあるので、install-package Rebus.Unity(またはプロジェクトにNuGetパッケージを追加するための好ましい方法のいずれかで)できます。

ここで、ハンドラーをUnityに登録するには、Unityが動作に関して他のすべてのコンテナーResolveAll(少なくとも私が知っているコンテナー)とは異なる動作をするという事実に注意する必要があります。これには、すべてのハンドラーが登録されている必要があります。名前付き登録として。

これを行うための正確なUnity構文を覚えていませんが、次のようになっていると思います。

container.RegisterType<IHandleMessages<SomeMessage>, MyMessageHandler>("id");

MyMessageHandlerのハンドラーとして登録するためSomeMessage。さまざまな登録関数には他にもいくつかのオーバーロードがあるため、ニーズに合ったものを見つけることができるはずですが、UnityではRebusがをResolveAll実行するため、ハンドラーを常にkey/idで登録する必要があることに注意してください。

于 2012-09-28T11:50:53.123 に答える
1

RebusでUnityを使用するには、次のタイプのIHandleMessagesを登録する必要があります

  • SubscriptionMessage
  • IRebusControlMessage
  • 物体

...IContainerAdapter.GetHandlerInstancesFor<T>が上記のタイプで呼び出されるため。

そして、私はそれを考えていないのではないかと心配しています。

インターフェイスを実装するタイプも指定せずに、インターフェイスをキーとして使用してタイプをUnityで解決することはできません。

素晴らしいRebusコントリビューターの1人がUnityを使用する例を投稿できれば素晴らしいと思います。

于 2012-10-01T13:36:55.363 に答える
0

上記のように、Unityは要求されたタイプのみを解決し、継承されたクラスまたはインターフェースを検索しません。

リフレクションを使用して目的の実装を見つけるUnityExtensionを実装する場合でも、ポリモーフィックリゾルブでUnityを使用する方法があります。ポリモーフィック機能とメソッドRegister<>およびHandle<>を備えたUnity用のRebusアダプターが必要でした。

これがUnityを使用したRebusのバージョンで、うまく機能します。

public class UnityContainerAdapter:IContainerAdapter、IDisposable {
public IBus Bus {get; 内部セット; }

private readonly IUnityContainer _unityContainer;
private readonly IHandlerRegistrator _handlerRegistrator;

public UnityContainerAdapter(IUnityContainer unityContainer)
{
    _unityContainer = unityContainer;

    _handlerRegistrator = _unityContainer
        .AddNewExtension<AllThatImplements>()
        .Configure<IHandlerRegistrator>();
}

public IEnumerable<IHandleMessages> GetHandlerInstancesFor<T>()
{
    return _unityContainer.ResolveAll<IHandleMessages<T>>();
}

public void Release(IEnumerable handlerInstances)
{
    foreach (IDisposable disposable in handlerInstances.OfType<IDisposable>())
        disposable.Dispose();
}

public void SaveBusInstances(IBus bus)
{
    Bus = bus;
    _unityContainer.RegisterInstance(typeof(IBus), bus);
    _unityContainer.RegisterType<IMessageContext>(new InjectionMember[1]
    {
        new InjectionFactory(c => (object) MessageContext.GetCurrent())
    });
}

public UnityContainerAdapter Register<THandler>()
{
    _handlerRegistrator.RegisterImplementingType<THandler>(typeof(IHandleMessages<>));
    return this;
}

public UnityContainerAdapter Handle<TMessage>(Action<TMessage> handler)
{
    _unityContainer.RegisterType<IHandleMessages<TMessage>, HandlerMethodWrapper<TMessage>>(Guid.NewGuid().ToString(), new InjectionConstructor(handler));
    return this;
}

internal class HandlerMethodWrapper<T> : IHandleMessages<T>
{
    private readonly Action<T> _action;

    public HandlerMethodWrapper(Action<T> action)
    {
        _action = action;
    }

    public void Handle(T message)
    {
        _action(message);
    }
}

public void Dispose()
{
    _unityContainer.Dispose();
}

#region - Unity Extionsion -
internal class AllThatImplements : UnityContainerExtension, IHandlerRegistrator
{
    protected override void Initialize() { }

    public void RegisterImplementingType<T>(Type implementationToLookFor)
    {
        var closedType = typeof(T);

        closedType.GetInterfaces()
                  .Where(x => x.IsGenericType)
                  .Where(x => x.GetGenericTypeDefinition() == implementationToLookFor)
                  .ToList()
                  .ForEach(x => Container.RegisterType(x, closedType, Guid.NewGuid().ToString()));
    }
}

internal interface IHandlerRegistrator : IUnityContainerExtensionConfigurator
{
    void RegisterImplementingType<T>(Type inheritedTypeToLookFor);
}
#endregion

}

于 2015-03-22T19:06:06.970 に答える