2

我对 Rebus 有几个新手入门问题。Rebus 自述文件中的所有精彩示例都使用温莎城堡,但我没有那个选项;相反,我必须使用 Unity。

我的第一个挑战是为 Unity IoC 容器找到合适的适配器,如示例所述:

var someContainerAdapter =
    new AdapterForMyFavoriteIocContainer(myFavoriteIocContainer);

我终于在这里找到了一些似乎可以完成这项工作的代码,但也许存在更好的容器,因为我必须自己实现IContainerAdapter接口(我想知道是否需要......)。

但我可以忍受那个...

我的下一个问题更糟,我还没有发现。在 Rebus Getting started-example 中,以下内容用于向 IoC 容器添加处理程序:

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

以上是 Windsor Castle 语法,我不知道 Unity 语法应该如何用于相同的操作。所以我在这里需要一些帮助。一个建议是,如果我可以参考一个适用于 Unity 的小型解决方案。

4

3 回答 3

5

我的建议是使用Rebus.Unity,它是 Rebus 的即用型 Unity 容器适配器,由一位出色的 Rebus 贡献者制作。

它有一个 NuGet 包,因此您可以install-package Rebus.Unity(或者以任何一种方式将 NuGet 包添加到您的项目中的首选方式)。

现在,为了向 Unity 注册处理程序,您应该知道 Unity 的行为与其他所有容器的行为不同ResolveAll至少是我所知道的那些),这要求您的所有处理程序都已注册作为命名注册。

我不记得执行此操作的确切 Unity 语法,但我认为它看起来有点像这样:

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

为了注册MyMessageHandlerSomeMessage. 各种注册函数还有其他几个重载,因此您应该能够找到适合您需要的一个 - 但请记住,对于 Unity,由于 Rebus 做了 a ResolveAll,您必须始终使用 key/id 注册处理程序

于 2012-09-28T11:50:53.123 回答
1

使用 Unity 和 Rebus 需要我注册以下类型的 IHandleMessages

  • 订阅消息
  • IRebusControlMessage
  • 目的

...因为使用上述类型调用 IContainerAdapter.GetHandlerInstancesFor< T >。

而且恐怕不是这个想法。

如果不指定实现接口的类型,我就无法统一使用接口作为 Key 来解析类型。

如果一位出色的 Rebus 贡献者可以发布一个使用 Unity 的示例,那就太好了。

于 2012-10-01T13:36:55.363 回答
0

如上所述,Unity 只解析请求的类型,它不查找继承的类或接口。

有一种方法可以将 Unity 与多态解析一起使用,但如果您实现一个使用反射来查找您所追求的实现的 UnityExtension。我们需要一个 Rebus 适配器来实现具有多态功能和方法 Register<> 和 Handle<> 的统一性。

这是我们使用 Unity 的 Rebus 版本,效果很好。

公共类 UnityContainerAdapter:IContainerAdapter,IDisposable {
公共 IBus 总线 { 获取;内部集;}

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 回答