0

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.

THX-1138
  • 21,316
  • 26
  • 96
  • 160
  • Why do you need to instantiate them? Shouldn't they be instantiated as part of the [Composition Root](http://blog.ploeh.dk/2011/07/28/CompositionRoot/) anyway? If not, do they share any common logic, for example, do you need to tell them to "shut down" when the application closes? Or to "initialize" after instantiation? ... – BatteryBackupUnit Nov 13 '14 at 08:19
  • @BatteryBackupUnit, fair questions. I've updated the question. – THX-1138 Nov 13 '14 at 15:23

1 Answers1

0

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)
}
Community
  • 1
  • 1
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • Is there a way to do kernel.GetAll for services without an interface, but decorated with an attribute? Something like: `kernel.GetAllWithAttribute()` – THX-1138 Nov 14 '14 at 16:33
  • no you can't do that. You can only use attributes for binding (conventions) but not for retrieving/instanciating. – BatteryBackupUnit Nov 14 '14 at 16:57