2010-09-07 2 views
3

Допустим, у меня есть веб-приложение ASP.NET MVC, которое состоит из множества сборок. Вот очень простой пример:Чья ответственность должна регистрировать типы с контейнером IoC?

  • MyApp.Web
    • веб-приложение
  • MyApp.Services
    • содержит интерфейсы и реализации доменных служб, например IOrderProcessor, DefaultOrderProcessor
  • MyApp.DAL
    • содержит интерфейсы и реализации хранилищ, например, IOrderRepository, SqlOrderRepository

Веб-приложение будет инициализировать контейнер IoC во время запуска (например, зарегистрировать контроллеры и т.д.). Я не уверен, чья ответственность за регистрацию доменных служб и репозиториев.

Что я сделал сейчас, это создать статический класс в каждой сборке, каждый из которых содержит метод, ответственный за регистрацию типов, содержащихся в сборке. Например. для сборки DAL:

namespace MyApp.DAL 
{ 
    public static class AssemblyInitialization 
    { 
    public static void RegisterTypes(IUnityContainer container) 
    { 
     var lm = new TransientLifestyleManager(); 
     container.RegisterType<IOrderRepository, SqlOrderRepository>(lm); 
     ... 
    } 
    } 
} 

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

Я не уверен, что это хорошая практика. Например, это решение связывает две сборки с конкретным контейнером IoC (Unity в примере, показанном выше). Кажется, это возможный анти-шаблон (similar to using the service-locator pattern).

Поэтому я ищу Ваше мнение о том, как это должно быть обработано, например:

  • должны все вещи регистрации обрабатываться главным приложением (веб-приложение)?
  • или это слишком много знало о содержании отдельных (автономных) сборок в главном приложении?
  • Должен ли я абстрагироваться от конкретного контейнера IoC с использованием самодельного интерфейса?
  • Другие вещи, чтобы рассмотреть?

ответ

1

Это всегда ответственность точки входа, в этом случае здесь находится ваш MyApp.Web. Обычно это «переходит в/вызывается из» вашего glabal.asax.

1

Запустите «загрузку» в вашей точке входа. Однако вы можете делегировать регистрацию каждой загруженной сборке, используя класс, реализующий IRegistration в этих сборках.

Это в значительной степени то, что вы делаете прямо сейчас.Но вместо использования статических классов вы можете найти реализации IRegistration через отражение при инициализации.

Поскольку вы используете MVC, взгляните на турбину, которая отлично справляется с этим. Или еще лучше, используйте его в своем приложении :)

+0

Что такое IRegistration, где оно определено? Не мог найти его нигде. Если это что-то из конкретного контейнера IoC, то, я думаю, это не будет большим улучшением по сравнению с моим текущим решением. – M4N

+0

Нет, это просто пример. Вы можете называть его чем угодно, IRegistration _could_ быть интерфейсом в вашем приложении. Когда приложение будет инициализировано, все классы, реализующие IRegistrations, будут загружены и выполнены. Таким образом, вы можете избежать использования статических классов и разместить регистрацию в логических местах (например, вместо десятков регистраций в global.asax) ... – Bertvan

+0

Ну, и вам все равно придется искать эти реализации самостоятельно. Но серьезно, посмотрите на MVC Turbine, он делает (среди прочего) именно это в среде ASP.NET MVC. – Bertvan

0

IMHO, ваш код должен отложить принятие этого решения как можно дольше - до последнего ответственного момента. Я использую Unity, поэтому я могу дождаться загрузки web.config, чтобы объявить, какие типы я хочу ввести.

Я считаю, что если вы не используете файл конфигурации для этого, вы делаете что-то неправильно. Цель использования среды DI заключается в уменьшении и/или удалении этих зависимостей времени компиляции.

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