2016-03-12 5 views
3

У нас есть веб-решение с autofac. Теперь мы хотим повторно использовать вещи в приложении Windows/консоли, где все доступно только тогда, когда сообщение приходит с корпоративной шины.Используйте фабрику для разрешения зависимостей

У меня есть следующие службы для повторного использования

public SettingsService : ISettingsService { 
    public readonly ITenantIdentifer _tenantIdentifier 
    public SettingsService (ITenantIdentifier tenantIdentifier) { 
     this._tenantIdentifier =tenantIdentifier; 
    } 
    // do other stuff 
} 

Текущая рабочая установка

ITenantIdentifier для webcontext просто зарегистрирован для WebApplication с помощью builder.RegisterType<WebTenantIdentifier>().As<ITenantIdentifier>();.
Evething работает нормально.

Наше предприятие автобус

Автобус предприятие не может решить ITenantIdentifier, пока сообщение не доступно. Итак, мы создали MessageTenantIdentifier и зарегистрировали завод.

public class MessageTenantIdentifier : ITenantIdentifier 
{ 
    public delegate MessageTenantIdentifier Factory(int tenantId); 
public MessageTenantIdentifier(int tenantId, IOtherDependency stuff) 
    { 
     _tenantId = tenantId; 
     // ... 
    } 
} 

// somewhere else the this is registered  
builder.RegisterType<MessageTenantIdentifier >().As<ITenantIdentifier>().AsSelf(); 
builder.RegisterGeneratedFactory<MessageTenantIdentifier.Factory>(); 

Проблема Завод может использоваться только тогда, когда сообщение обрабатывается в

public class MsgTypeHandler : IHandleMessages<MsgType> 
{ 
    public MsgTypeHandler(ISettingsService settingsService, MessageTenantIdentifier factory) { ...} 
    public async Task Handle(MsgType message) 
    { 
     var tenantId = message.TenantId; 
     // THIS IS THE MOMENT I CAN CONFIGURE THE MessageTenantIdentifier 
     var tenantIdentifier = factory.Invoke(tenantId); 

     // but this factory is not used against the ISettingsService. The service to be reused. <== THE REAL PROBLEM 
    } 
} 

Вопрос

Итак, как я могу решить эту проблему? Например. как настроить регистрацию MessageTenantIdentifier в сервисной шине? Или моя настройка зависимости просто неправильная?

ответ

2

Если MsgTypeHandler класс нуждается в ISettingsService, но весь объект граф не может быть решена до тех пор, арендатор ID не доступен, что означает, что MsgTypeHandler является Composition Root. Это нормально, но это означает, что именно здесь вы разрешаете весь графический объект, поэтому не добавляйте сюда отдельные услуги; вместо этого введите нужный вам завод:

public class MsgTypeHandler : IHandleMessages<MsgType> 
{ 
    public MsgTypeHandler(ISettingsServiceFactory factory) {...} 

    public async Task Handle(MsgType message) 
    { 
     var tenantId = message.TenantId; 
     ISettingsService svc = this.factory.Create(tenantId); 

     // User svc here... 
    } 
} 
+0

Итак, я должен написать свой собственный заводский метод, потому что корень композиции не может зависеть от DI-рамки в этом случае. (Все еще интересуется, не имеет ли автофака этого решения ... – dampee

+0

@dampee Вы можете [писать завод по-разному] (http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory), включая сдачу ваш контейнер DI заботится о деталях. –

+0

Я понимаю. Мне действительно нужно прочитать книгу по этой теме. Ваша книга по-прежнему хорошая ссылка, или вы бы посоветовали кому-нибудь другому? – dampee

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