Подтвердить что ты не робот

Autofac в веб-приложениях, где я должен хранить контейнер для легкого доступа?

Я все еще довольно новичок в использовании Autofac, и одна вещь, которую я пропустил в документации, и примеры - это то, как легко добраться до сконфигурированного контейнера из разных мест в веб-приложении.

Я знаю, что я могу использовать контроллер Autofac factory для автоматического разрешения зависимых от конструктора зависимостей для контроллеров, но как насчет других вещей, которые вам могут понадобиться решить, которые еще не введены.

Есть ли очевидный шаблон, о котором я не знаю?

Спасибо!

4b9b3361

Ответ 1

Прежде всего старайтесь не злоупотреблять контейнером IoC. Он отлично подходит для "проводки" контроллеров, представлений и служб, но объекты, которые необходимо создать во время выполнения, должны создаваться объектами factory, а не контейнером. В противном случае вы получите Container.Resolve вызывает весь ваш код, привязывая его к вашему контейнеру. Эти дополнительные зависимости преследуют цель использования IoC. В большинстве случаев я могу получить только разрешение одной или двух зависимостей на верхнем уровне моего приложения. Контейнер IoC затем рекурсивно разрешит большинство зависимостей.

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

public class Container : IContainer
{
    readonly IWindsorContainer container;

    public Container()
    {
        // Initialize container
        container = new WindsorContainer(new XmlInterpreter(new FileResource("castle.xml")));

        // Register yourself
        container.Kernel.AddComponentInstance<IContainer>(this);
    }

    public T Resolve<T>()
    {
        return container.Resolve<T>();
    }
}

Я переношу контейнер в класс Container следующим образом. Он добавляет себя в упакованный контейнер в конструкторе. Теперь классы, которым нужен контейнер, могут быть введены IContainer. (пример для Castle Windsor, но он, вероятно, может быть адаптирован для AutoFac)

Ответ 2

Autofac "способ" должен иметь параметр конструктора IContext. Autofac будет вводить объект, который можно использовать для разрешения типов.

Контекст обычно является контейнером за кулисами, IContainer реализует интерфейс IContext, хотя IContext ограничивается только выполнением разрешений.

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

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

Обновление: в Autofac 2, IContext называется IComponentContext.

Ответ 3

Наличие контейнера МОК в глобальном масштабе не является лучшей практикой. Даже передающий контейнер не рекомендуется.

Если инъекция зависимостей не может быть использована (вам необходимо создать объекты \request после создания компонента), вы можете:

Ответ 4

Ответ Питера Лиллевольда выше - вы можете получить доступ к контейнеру из любого компонента, зависнув от интерфейса IContext.

Если вам действительно нужна действительно фактическая ссылка на контейнер, см. Autofac.Integration.Web.IContainerProviderAccessor.

Ответ 5

Обычный способ сделать это - сохранить контейнер в статической переменной в вашем глобальном классе приложения.