2

I just spent the last 48 hours trying to make the above happen and while I think Rhino Service Bus is fabulously useful their documentation leaves a lot to be desired. Having solved the problem I was facing I thought it might be useful for others to see what I did... so here it is. Hopefully someone will find it so.

I am developing a WPF/PRISM/Unity reporting application and wanted to use a service bus to allow the app to be an occasionally connected one getting its data via bus messages when connected over a VPN. I introduced the bus into the Bootstrapper for the App and hosted it in the Rhino DefaultHost. This did allow the bus to operate and messages passed back and forth quite satisfactorily until I tried to inject the IEventAggregator into the constructor of a class which was implementing the ConsumerOf interface.

I kept getting the error "IEventAggregator is an interface and cannot be constructed. Are you missing a type registration" and I didn't know why as the Event aggregator was registered as a singleton in the application's Bootstrapper.

The problem seems to be that registering the class which implements ConsumerOf ties that class to the internal Unity container for the bus which appears to override any connection that class may have to the application container.

The solution (which I admit is glaringly obvious once you see it) is to make the bus container a child container of the application container so that any failed resolutions (can't find IEventAggregator?!) are passed to the parent for resolution (oh look, here it is!!).

Here's how that can be achieved...

protected override void ConfigureContainer()
{
    base.ConfigureContainer();

    //Singletons
    var accountData = new AccountService();

    //ServiceBus
    var host = new DefaultHost();
    host.Start<ESBBootStrapper>();

    var childContainer = Container.CreateChildContainer();
    new RhinoServiceBusConfiguration().UseUnity(childContainer).Configure();
    var bus = childContainer.Resolve<IStartableServiceBus>();
    bus.Start();

    //Application Instances
    Container.RegisterInstance(bus as IServiceBus, new ContainerControlledLifetimeManager());

}

I also needed to modify the same override in the ESBBootstrapper in order to find the classes in the application which were implementing ConsumerOf. This was done as follows...

public class ESBBootStrapper : UnityBootStrapper
{
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        foreach (var current in AppDomain.CurrentDomain.GetAssemblies())
        {
            ConfigureConsumers(current);
        }
    }
}
4

0 回答 0