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.

Était-ce utile?

La 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top