2010-12-06 2 views
3

Я только начинаю с каркасов IoC и играю с Autofac.IoC using Autofac

В следующем примере кода, где я регистрирую 2 совершенно разных класса (в global.asax), которые реализуют один и тот же интерфейс, мне интересно, как мы гарантируем, что правильный используется Autofac? В настоящее время один из моих контроллеров, который принимает IPhotoBlogRepository в качестве своего конструктора, передается либо PhotoBlogRepository ИЛИ TestRepository, в зависимости от того, который появляется первым/последним в приведенном ниже коде.

builder.RegisterType<PhotoBlogRepository>().As<IPhotoBlogRepository>(); 
builder.RegisterType<TestRepository>().As<IPhotoBlogRepository>(); 

ответ

7

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

Если вы намерены поддерживать несколько реализаций, ваш контроллер может зависеть от IEnumerable<IPhotoBlogRepository>. Autofac предоставит контроллеру коллекцию всех зарегистрированных сервисов, реализующих этот интерфейс.

Если контроллеру требуется еще более мелкозернистый контроль, взгляните на то, как Autofac supports metadata.

Это сказало: из вашего образца я вижу, что вы регистрируете тестовую реализацию интерфейса. В модульных тестах я редко разрешаю SUT (ваш контроллер в этом случае) из контейнера, а скорее создаю его непосредственно. Это устраняет проблему «замены» реальных сервисов поддельными, поскольку вы всегда будете передавать их непосредственно конструктору контроллера.

+0

Извините, мой код вводит в заблуждение словом «Test». Тестирования модулей не было, я просто создал несколько фиктивных классов, чтобы попытаться узнать, как все это работает, и случилось создать один из моих тестов TestRepository. – marcusstarnes 2010-12-06 17:51:01

2

Как было отмечено выше, метаданные, вероятно, как вы хотите, чтобы пойти с этим, но если вы просто хотите, чтобы просто убедиться, что первая реализация выбрана, то вы должны использовать PreserveExistingDefaults() для всех дополнительных регистраций, то есть:

builder.RegisterType<PhotoBlogRepository>().As<IPhotoBlogRepository>(); 
builder.RegisterType<TestRepository>().As<IPhotoBlogRepository>().PreserveExistingDefaults(); 

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

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