Ninject: instantiate a service during configuration

86 Views Asked by At

I want to configure my ninject container using conventions AND create instances of all selected services at the same time. My current solution is:

        var singletons = new List<Type>();
        kernel.Bind(x =>
            x.FromThisAssembly() // Scans currently assembly
                .SelectAllClasses()
                .WithAttribute<SingletonAttribute>()
                .Where(type =>
                {
                    var include = MySpecialFilterOfSomeSort(type);
                    if (include)
                    {
                        singletons.Add(type);
                    }
                    return include;
                }) // Skip any non-conventional bindings
                .BindDefaultInterfaces() // Binds the default interface to them
                .Configure(c => c.InSingletonScope()) // Object lifetime is current request only
            );
            singletons.ForEach(s => kernel.Get(s));

MORE
I have an intra-process service bus. Some components are decorated with [Singleton] and will register themselves with the service bus:

// the constructor
public FooEventsListenerComponent(IServiceBus serviceBus) {
    serviceBus.Subscribe<FooEvent>(e => HandleFooEvent(e));
}

I need a place in the app to create instances of all the service bus observers. Doing it next to type mapping is convenient (but is it appropriate?) because 1. types are already enumerated, 2. I have an access to the DI container.

1

There are 1 best solutions below

2
On BEST ANSWER

In the case you describe i think it would make sense to make service bus registration explicit. To expand on my answer to your other question about conventions:

Create an interface for the listeners:

public interface IServiceBusSubscriber
{
    void SubscribeTo(IServiceBus serviceBus);
}

then you can adapt your convention to bind all types which inherit from IServiceBusSubscriber to their default interface (then they must be named like FooServiceBusSubscriber and BarServiceBusSubscriber) or to IServiceBusSubscriber explicitly.

After the kernel is initialized with all bindings just do:

IServiceBus serviceBus = kernel.Get<IServiceBus>();
foreach(IServiceBusSubscriber subscriber in kernel.GetAll<IServiceBusSubscriber>())
{
    subscriber.SubscribeTo(serviceBus)
}