1

У меня есть следующие классы, с которыми у меня возникают проблемы с разрешением SimpleInjector.Как зарегистрировать услугу условно на основе верхнего большинства именных пространств

Config Интерфейс

Namespace Infrastructure.Base.Interfaces 
public interface ILdapConfigService 
{ 
    ..... 
} 

интерфейс Session

Namespace Infrastructure.Base.Interfaces 
public interface ISessionService 
{ 
    LdapConnection GetConnection(); 
} 

Реализация Session

Namespace Infrastructure.Base.Services 
public class SessionService : ISessionService { 

    ILdapConfigService _ldapConfigService;   
    public SessionService (ILdapConfigService ldapConfigService) 
    { 
     _ldapConfigService = ldapConfigService; 
    } 

    public LdapConnection GetConnection() 
    { 
     ......... 
    } 
} 

Config Service Реализация 1

namespace Infrastructure.Old.Services 
public class OldConfigService : ILdapConfigService 
{ 
    .... 
} 

Config Service Реализация 2

namespace Infrastructure.New.Services 
public class NewConfigService : ILdapConfigService 
{ 
    .... 
} 

Идея заключается в том, чтобы иметь ISessionService и SessionService в базовом проекте. Затем есть разные проекты, которые реализуют LdapConfigService орудия ведьмы ILdapConfigService от базового проекта.

Различные проекты будут иметь службы, которые также используют репозиторий в базовом классе.

Мне нужно знать, как зарегистрировать эти интерфейсы, или даже можно зарегистрировать его вот так?

Infrastructure.New.Service.SomeService использует Infrastructure.Base.Interfaces.IRepository. Infrastructure.Old.Service.SomeOtherService использует Infrastructure.Base.Interfaces.IRepository.

Infrastructure.Base.Repositories.Repository инвентарь Infrastructure.Base.Interfaces.IRepository. Infrastructure.Base.Repositories.Repository использует Infrastructure.Base.Interfaces.ISessionService.

Infrastructure.Base.Services.SessionService инвентарь Infrastructure.Base.Interfaces.ISessionService. Infrastructure.Base.Services.SessionService использует Infrastructure.Base.Interfaces.ILdapConfigService.

Infrastructure.New.Services.LdapConfigService инвентарь Infrastructure.Base.Interfaces.ILdapConfigService.

Infrastructure.Old.Services.LdapConfigService инвентарь Infrastructure.Base.Interfaces.ILdapConfigService.

Как зарегистрировать эту логику с помощью Simple Injector. Я использовал RegisterConditional, но это не совсем сработало, потому что потребитель ILdapConfigService сидит в базе.

container.RegisterConditional< 
    ILdapConfigService, 
    Old.Services.LdapConfigService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("Old")); 

container.RegisterConditional< 
    ILdapConfigService, 
    New.Services.LdapConfigService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("New")); 

container.Register<ISessionService, SessionService>(); 
container.Register<ILdapRepository, LdapRepository>(); 

Каждый LdapConfigService разговаривает с app.config, где вся важная информация загружается в.

База выполняет всю реализацию до OpenLdap, исключая конфигурацию, которая должна быть введена в SessionService, поэтому она ведет переговоры с нужным сервером. Кто знал, что абстракция может стать настолько сложной.

Является ли мой шаблон дизайна ошибочным?

+0

Так 'New.SomeService' использовать' New.LdapConfigService' косвенно и 'Old.SomeOtherService' использовать' Old.LdapConfigService' косвенно? – Steven

+0

Yehp вы правы, потому что каждый сервис конфигурации находится на уникальном проекте –

ответ

1

Является ли мой дизайн шаблоном, возможно, неправильным?

До тех пор, пока вы уверены, что не нарушаете Принцип замены Лискова, я не могу найти в нем каких-либо недостатков, хотя эта конструкция немного затрудняет настройку контейнера.

Я думаю, что трюк здесь состоит в том, чтобы создать две версии ISessionService; один для материала New, один для предметов Old. Это позволяет дифференцировать данные по типам. Это необходимо, потому что у Simple Injector RegisterConditional есть ограничение, которое позволяет вам смотреть только на прямой тип регистрации. Вы регистрируете ILdapConfigService условно, но он всегда вводится в SessionService. Предоставляя каждому ILdpConfigService свои ISessionService, вы разрешаете создавать условия на основе потребителей ISessionSerice.

Это ограничение простого инжектора является преднамеренным и существует, чтобы предотвратить использование пользователем недопустимых конфигураций. Например, если SessionService зарегистрирован как одиночный, для него будет невозможно иметь два разных ILdapConfigServices.

С момента создания двух ISessionService реализация - это «трюк конфигурации», вы можете просто определить вторую реализацию как часть вашего корня композиции и наследовать ее от первого. Поступая таким образом вы можете матч на основе типов, как показано ниже:

class NewSessionService : SessionService { 
    public NewSessionService(ILdabConfigService s) { ... } 
} 

container.RegisterConditional<ISessionService, SessionService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("Old")); 

container.RegisterConditional<ILdabConfigServices, Old.LdapConfigService>(
    c => c.Consumer.ImplementationType == typeof(SessionService)); 


container.RegisterConditional<ISessionService, NewSessionService>(
    c => c.Consumer.ImplementationType.Namespace.Contains("New")); 

container.RegisterConditional<ILdabConfigServices, New.LdapConfigService>(
    c => c.Consumer.ImplementationType == typeof(NewSessionService)); 
+0

Спасибо. Я подумал, что этот подход будет самым простым способом получить все это. Тем не менее, я нашел массивный недостаток в своем дизайне, библиотеки классов не будут читать из соответствующих файлов App.config, поэтому я должен был все вернуть в один проект. Я отправлю свое решение в качестве ответа, но ваш вопрос будет таким же правильным. –

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