Question

I have seen the IoC feature in Membus that i have tried to hookup to Simple Injector

IEnumerable<object> IocAdapter.GetAllInstances(Type desiredType)
{
var found = SimpleInjectorContainer.GetAllInstances(desiredType);
return found;
}

The idea is that I will register automatically all my types with RegisterManyForOpenGeneric(typeof<CommandHandler<>),typeof<CommandHandler<>).Assembly).

No doubt for normally a good reason, SimpleInjector will not allow multiple registrations - however, I want to do this to put different aspects/concerns of command handling to be implemented by different handlers.

public void MembusBootstrap()
{
    this.Bus = BusSetup.StartWith<Conservative>()
    .Apply <IoCSupport>(c =>
    {
        c.SetAdapter(SimpleInjectorWiring.Instance)
           .SetHandlerInterface(typeof(HandleCommand<>));
    })
    .Construct();
}

public void SimpleInjectorBootstrap()
{
    this.Container.Register<HandleCommand<AccountCreatedCommand>,
        SetupNewAccountCommandHandler();

    // next line will throw
    this.Container.Register<HandleCommand<AccountCreatedCommand>,
        LogNewAccountRequestToFile>();
}

Certainly the IEnumerable<object> IocAdapter.GetAllInstances(Type desiredType) interface from membus expect a collection so multiple handlers can be called.

What would be the best way forward to marry Membus with SimpleInjector IoC?

Footnote

I have seen other ways to wireup menbus by convention:

public interface YetAnotherHandler<in T> {
  void Handle(T msg);
}

public class CustomerHandling : YetAnotherHandler<CustomerCreated>
...

var b = BusSetup  
  .StartWith<Conservative>()  
  .Apply<FlexibleSubscribeAdapter>(c => c.ByInterface(typeof(YetAnotherHandler<>))  
  .Construct();

var d = bus.Subscribe(new CustomerHandling());  

But I would really like to stick with the IoC container to handle the lifetime scope, and to avoid instantiating command handlers and manually wiring them before they are required.

Was it helpful?

Solution

You can have multiple registrations. Here is an example (apologies but my PC died today and I am writing this in notepad):

SimpleInjectorContainer.RegisterManyForOpenGeneric(typeof(CommandHandler<>),
    AccessibilityOption.PublicTypesOnly,
    (serviceType, implTypes) => container.RegisterAll(serviceType, implTypes),
    AppDomain.CurrentDomain.GetAssemblies()
);

and they can be retrieved with:

public IEnumerable<CommandHandler<T>> GetHandlers<T>()
    where T : class
{
    return SimpleInjectorContainer.GetAllInstances<CommandHandler<T>>();
}

you'll find these versions of the RegisterManyForOpenGeneric and GetAllInstances methods described here

I use this technique to support a publish/subscribe framework. You can have n number of independent CommandHandler's

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top