2

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.

Steven
  • 166,672
  • 24
  • 332
  • 435
morleyc
  • 2,169
  • 10
  • 48
  • 108
  • As additional information, [this blog post here](http://realfiction.net/go/216) (disclaimer - my site) outlines how you connect MemBus to a DI Container these days. – flq Apr 20 '13 at 20:41
  • thanks for creating the membus tag I did not have enough mana to create :) This leads me on to a second related question about `SetHandlerInterface` here http://stackoverflow.com/questions/16125285/multiple-types-for-sethandlerinterface-with-membus-and-ioc-container – morleyc Apr 20 '13 at 21:17

1 Answers1

2

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

qujck
  • 14,388
  • 4
  • 45
  • 74
  • Do note though that the order of those implementations in the registered collection is nondeterministic. If the order is important, pass a sorted list onto the RegisterAll method. For instance: `implTypes.OrderBy(t => t.Name)`. – Steven Apr 21 '13 at 07:34