7

My Service Interfaces имеет пространство имен Services.InterfacesПростые Injector Регистрация Все сервисы из пространства имен

Реализация Сервисного интерфейсов имеет пространство имен Web.UI.Services

У меня есть 2 реализаций сервиса, например

  • IUserService, которому необходимо зарегистрироваться в UserService
  • ICountryService, которому необходимо зарегистрироваться в CountryService

Вот как я в настоящее время регистрирую эти службы с помощью SimpleInjector.

container.Register<IUserService, UserService>(); 
container.Register<ICountryService, CountryService>(); 

Проблема: Если у меня есть более 100 услуг, чтобы преувеличить немного. Мне нужно пойти и добавить строку для каждой службы.

Как я могу зарегистрировать все реализации из одной сборки во всех интерфейсах из другой сборки, используя Simple Injector?

ответ

6

Вы можете сделать это, запрашивая через сборку с помощью LINQ и отражения и регистрации всех типов:

var registrations = 
    from type in typeof(UserService).Assembly.GetExportedTypes() 
    where type.Namespace.StartsWith("Services.Interfaces") 
    where type.GetInterfaces().Any() 
    select new { Service = type.GetInterfaces().Single(), Implementation = type }; 

foreach (var reg in registrations) { 
    container.Register(reg.Service, reg.Implementation); 
} 

Это описано here.

Если у меня есть более 100 услуг, чтобы немного преувеличивать. Мне нужно пойти и добавить строку для каждой службы.

Если это так, я бы сказал, что с вашим дизайном что-то не так. Тот факт, что вы называете ваши услуги IUserService и ICountryService, является указанием, что вы нарушаете правила по Single Responsibility, Open/closed и Interface Segregation Principles. Это может вызвать серьезные проблемы с ремонтопригодностью.

Для альтернативной конструкции взгляните на статьи thesetwo. Описанная конструкция обеспечивает гораздо более высокий уровень ремонтопригодности, значительно упрощает регистрацию ваших услуг и делает использование сквозных проблем для игры с детьми (особенно с Simple Injector).

+3

Steven: Мне любопытно, как вы можете сказать, что OP нарушает SRP, OCP только от имени интерфейса? Я этого не вижу. –

+0

Стивен. Благодарим за это, 100 услуг - это преувеличение. Также ICountryService и IUserService полностью не связаны. Спасибо за статьи, я пойду прочитаю это. –

+0

@ShiramSakthivel прочитал статью [this] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92), и вам станет ясно. В статье объясняется это. – Steven

7

Вы ищете «Конвенция по конфигурации». Простой инжектор вызывает это Batch/Automatic registration.

В то время как основные контейнеры DI обеспечивают API для этого, кажется Простой инжектор оставляет его у нас; С бит отражения и LINQ можно зарегистрировать типы в виде пакета, поэтому Простой инжектор не предоставляет никаких специальных API для этого.

Идея заключается в том, что вы сканируете сборку для конкретных типов с некоторым соглашением, глядя на то, реализует ли он какой-либо интерфейс; если это так, то зарегистрируйте его.

Вот образец вытащил из выше ссылке:

var repositoryAssembly = typeof(SqlUserRepository).Assembly; 

var registrations = 
    from type in repositoryAssembly.GetExportedTypes() 
    where type.Namespace == "MyComp.MyProd.BL.SqlRepositories" 
    where type.GetInterfaces().Any() 
    select new { Service = type.GetInterfaces().Single(), Implementation = type }; 

foreach (var reg in registrations) { 
    container.Register(reg.Service, reg.Implementation, Lifestyle.Transient); 
} 

Вы можете изменить этот код, чтобы применить конвенцию и зарегистрировать типы в пакетном режиме.