2012-05-23 7 views
2

Я пытаюсь решить проблему с контейнером Autofac IoC.Использование Autofac в библиотеке классов

Мой веб-приложение имеет следующие части:

  1. веб-приложения
  2. ядра (Shared) библиотеки.
  3. Модули

Каждый модуль имеет ссылку на библиотеку ядра (который включает в себя код ниже), и каждый модуль должен иметь возможность зарегистрировать свои собственные типы. Поэтому мне нужно иметь один общий контейнер между приложением и модулями.

У меня есть код на следующий контейнер:

public static class DependencyContainer 
    { 
     public static IContainer Container { get; private set; } 

     public static ContainerBuilder Builder { get; private set; } 

     public static void RegisterType<TFrom, TTo>() where TTo : TFrom 
     { 
      Builder.RegisterType<TTo>().As<TFrom>(); 
     } 

     public static T ResolveType<T>() 
     { 
      return Container.Resolve<T>(); 
     } 

     public static void InitContainer() 
     { 
      Builder = new ContainerBuilder(); 
      Container = Builder.Build(); 
     } 
    } 

Этот контейнер находится в главном (ядро) библиотеке. Когда приложение запускается, он вызывает InitContainer() из global.asax. После этого я пытаюсь зарегистрировать новый тип из своих модулей приложения, используя метод RegisterType().

Но после этого я не могу разрешить любые типы. Он просто выдает исключение, что этот тип не был зарегистрирован.

Основная идея этого кода заключается в том, что я смогу разрешить любой тип из любого модуля и веб-приложения, используя только один общий контейнер.

Может ли кто-нибудь помочь мне с этой проблемой? Есть ли более элегантное архитектурное решение для использования одного общего контейнера IoC между несколькими библиотеками?

Заранее благодарен!

ответ

3

Ваш дизайн ведет к Service Locator anti-pattern. Предотвратите определение контейнера в основной библиотеке и разрешите всем ссылаться на него. Используйте инъекцию зависимостей и настройте контейнер в Composition Root, ваш путь запуска приложения (в вашем случае корень композиции будет частью вашего веб-приложения).

Вы можете воспользоваться Autofac Module feature, а в корне композиции вы можете зарегистрировать этот модуль.

builder.RegisterModule(new CarTransportModule()); 

Но вы можете определить модуль регистрации классов как статические, а также, что еще проще:

MyApp.SomeModule.SomeModuleBootstrapper.Register(builder); 
+0

+1 для использования модулей. Однако я бы использовал Reflection для поиска и загрузки всех модулей – jgauffin

+0

-1 для использования модулей. Мне не нравятся модули ;-) – Steven

+0

почему? И как бы вы решили это? – jgauffin

1

Проблема решена - мы должны вызвать container.Build() только после регистрации всех наших зависимых ...

+0

+1, в то время как другая дискуссия о локаторах и модулях обслуживания интересна (и важна), это не проблема – galaktor

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