Использование DI и IoC с ASP.MVC 3, как настроить мои контроллеры для правильного разрешения новых типов? - PullRequest
3 голосов
/ 22 января 2012

Я читал книгу Марка Симанна Внедрение зависимостей в .NET и его сообщение в блоге относительно DI Composition Roots .

И я нахожусь в процессе рефакторинга вызовов моего контейнера приложения ASP.MVC 3 из моих контроллеров в корень композиции.

Раньше я разрешал типы внутри моего контроллеракак это.

[HttpGet]
public ActionResult Create()
{
    // Don't do this...
    var color = MvcApplication.Container.Resolve<IColor>();                           
    return View(color);
}

После прочтения книги Марка я понимаю, что это менее чем идеально, поэтому я настроил свое MVC-приложение для внедрения репозитория в контроллер при запуске приложения, используя класс, производный от IControllerFactory, как описано в книге Марка.в разделе 7.2.1.

Если я не должен вызывать контейнер IoC напрямую из моего контроллера ASP.MVC 3, используя шаблон Service Locator , как и где создавать новые типы?Каждый контроллер индивидуален, поэтому я хочу общий способ разрешения новых типов.

Я мог бы создавать экземпляры типов, например, так, как это, но в некотором роде победило бы цель.

[HttpGet]
public ActionResult Create()
{
   // Don't do this...
   var color = new Color();
   return View(color);
}

Должен ли я делать инъекцииобщая фабрика в мой контроллер вместе с общим хранилищем и использовать ее для создания новых типов?Есть ли лучший способ?

РЕДАКТИРОВАТЬ

Я понимаю, что это похоже на другой ТАК вопрос , но мои сущности имеют зависимости, которые необходимо решитьперед передачей их на просмотр.

Ответы [ 2 ]

2 голосов
/ 22 января 2012

Вы хотите создать контейнер и зарегистрировать сервисы в global.asax (включая ваши контроллеры) при запуске приложения. Вы также хотите предоставить свою собственную реализацию для IControllerFactory, которая использует контейнер, который я только что описал. Сообщите приложению об использовании новой фабрики контроллеров, установив proprty ControllerBuilder.Current.SetControllerFactory.

Подробнее здесь: http://bradwilson.typepad.com/blog/2010/07/service-location-pt2-controllers.html

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

Одним из подходов будет следующий

public interface IColorFactory
{
  IColor GetColor();
}

// this implementation is registered with the container
public class DefaultColorFactory : IColorFactory
{
  // this implementation is the only one that knows the details of the IColor implementation
  public IColor GetColor() {  return new Color(); } 
}

public class MyController : ControllerBase
{
  private readonly IColorFactory _colorFactory;
  public MyController(IColorFactory cf)
  {
    _colorFactory = cf;
  }

    [HttpGet]
    public ActionResult Create()
    {
      return View(_colorFactory.GetColor());
    }
}
2 голосов
/ 22 января 2012

В этом вопросе .

есть некоторая информация об использовании сервисного локатора.

Вы всегда можете разобраться с зависимостью через конструктор Controller:

 public class HomeController : Controller
    {

    private readonly IColor _iColor;

    public HomeController(IColor iColor)
    {

    _iColorService = iColor;
    }

    [HttpGet]
    public ActionResult Create()
    {
       var color = _iColor;
       return View(color);
    }

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