Лучшие практики для настройки контейнера IoC в корне композиции Asp .Net MVC - PullRequest
6 голосов
/ 08 ноября 2011

Я создаю приложение ASP .Net MVC 2 и хочу следовать идеям из книги Марка Симанна «Внедрение зависимостей в .Net», поэтому я зарегистрировал свою собственную фабрику контроллеров в файле Global.asax и настраиваюконтейнер внутри фабрики контроллеров выглядит так:

public IController CreateController(RequestContext context, Type controllerType)  
{  
   var container = new Container();
   object controller;

   if(controllerType == typeof(MyControllerOne)
   {
      container.Configure(r => r.
         For<IService>().
         Use<ServiceOne>());
   }
   else if(controllerType == typeof(MyControllerTwo)
   {
       container.Configure(r => r.
          For<IService>().
          Use<ServiceTwo>());
   }
   ......

   return container.GetInstance(controllerType) as IController;
}

Теперь этот код работает (хотя возможно, что у меня может быть ошибка где-то, поскольку я пишу это по памяти), зависимости разрешаются, иправильный контроллер создается с правильной зависимостью каждый раз, но кажется, что для каждого запроса контейнер настраивается для разрешения зависимостей, которые будут необходимы в этот момент.Итак, мои вопросы:

  • Разве это не избыточно?
  • Разве конфигурация контейнера не должна выполняться в Global.asax, так что это делается только один раз?Если так, как это могло быть сделано?
  • Как будет сконфигурирован контейнер, как я это делаю, как повлияет время жизни объекта?Я имею в виду, что в конечном итоге появятся репозитории, которые должны иметь одноэтапное время жизни, некоторые другие должны быть созданы один раз по HTTP-запросу, и так далее.Какие могут быть последствия?

Любые комментарии, идеи и / или предложения будут высоко оценены.

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

1 Ответ

4 голосов
/ 08 ноября 2011

Действительно, избыточно условно регистрировать каждый контроллер по запросу.С StructureMap фабрика контроллеров должна выглядеть следующим образом:

public class StructureMapControllerFactory : DefaultControllerFactory
{
    private readonly IContainer container;

    public StructureMapControllerFactory(IContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        this.container = container;
    }

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        return (IController)this.container.GetInstance(controllerType);
    }
}

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

this.Scan(x =>
{
    x.AssemblyContainingType<HomeController>();
    x.AddAllTypesOf<IController>();
    x.Include(t => typeof(IController).IsAssignableFrom(t));
});

Это в основном просто следование шаблону Register Resolve Release .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...