IoC с использованием Autofac - PullRequest
3 голосов
/ 06 декабря 2010

Я только начинаю с IoC-фреймворков и играю с Autofac.

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

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

Ответы [ 2 ]

7 голосов
/ 06 декабря 2010

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

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

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

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

2 голосов
/ 07 декабря 2010

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

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

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

...