2014-11-13 2 views
0

Я хочу настроить контейнер ninject с помощью условных обозначений И одновременно создавать экземпляры всех выбранных сервисов. Мое текущее решение:Ninject: создать экземпляр службы во время конфигурации

 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
У меня есть автобус службы внутри процесса. Некоторые компоненты украшены [Singleton] и зарегистрируют себя с сервисной шиной:

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

мне нужно место в приложении, чтобы создать экземпляры всех наблюдателей шинного сервисными. Выполнение этого рядом с сопоставлением типов удобно (но подходит ли оно?), Потому что 1. типы уже перечислены, 2. У меня есть доступ к контейнеру DI.

+0

Почему нужно инициализировать их? Не должны ли они быть внедрены как часть [Корень композиции] (http://blog.ploeh.dk/2011/07/28/CompositionRoot/)? Если нет, разделяют ли они какую-либо общую логику, например, вам нужно сказать им «закрыть», когда приложение закрывается? Или «инициализировать» после создания экземпляра? ... – BatteryBackupUnit

+0

@BatteryBackupUnit, честные вопросы. Я обновил вопрос. –

ответ

0

В случае, когда вы описываете, я думаю, что было бы разумно сделать регистрацию служебной шины явной. Для расширения my answer на другой Ваш вопрос о конвенциях:

Создать интерфейс для слушателей:

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

, то вы можете адаптировать вашу конвенцию, чтобы связать все типы, которые наследуют от IServiceBusSubscriber их интерфейс по умолчанию (то они должны быть названы как FooServiceBusSubscriber и BarServiceBusSubscriber) или IServiceBusSubscriber явно.

После ядра инициализируется со всеми привязками просто сделать:

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

Есть ли способ сделать kernel.GetAll для сервисов без интерфейса, но украшен атрибутом? Что-то вроде: 'kernel.GetAllWithAttribute ()' –

+0

нет, вы не можете этого сделать. Вы можете использовать атрибуты для привязки (условные обозначения), но не для получения/инициализации. – BatteryBackupUnit

Смежные вопросы