ОК,
Я уверен, Джереми Миллер исправит мой пост и даст вам настоящую правду, но идея иметь тот пользовательский Controller factory
, который использует StructureMap
дляСоздайте контроллеры, потому что Controller class
является классом ключей , где большая часть логики запускается и происходит (да, есть фильтры действий и тому подобное, что происходит раньше, но давайте будем проще) - и для этого необходимо предварительно настроить все зависимости, прежде чем начнется любая логика.
Итак, идея такова.Если вся логика и магия-единорог происходят в методах Controllers
, то когда мы в первый раз введем метод ... нам нужно уже настроить все наши требования.Что еще более важно, каждый метод в любом контроллере не должен заботиться о том, какие требования (например, экземпляры) он имеет ... только этот кто-то откуда-то... уже принял это решение и дал мне все важные объекты, которые нам могут понадобиться.
Это ядро DI / IoC.
Итак, давайте воспользуемся действительно простым кодомчтобы объяснить это, потому что я плохо разбираюсь в вещах.
Предположим, у нас есть следующий метод в контроллере: -
public ActionMethod Index()
{
// List all Products.
}
Довольно просто.Просто перечисляет некоторые продукты в браузере.Итак, первое, что вам нужно спросить, это -> что такое Products
?откуда они?Ну, метод контроллера не задает этот вопрос вообще.На самом деле, это НЕ КАСАЕТСЯ откуда они пришли.Его заботит только то, что он имеет что-то , то есть Product
.
Так что, когда мы используем этот метод, нам также не нужно заботиться о том, где находится информация о продукте.Мы просто хотим сделать что-то с этими вещами, которые называются Products
'.
Хорошо ... так что давайте сделаем что-то с этим ...
public ActionMethod Index()
{
var products = _myProductService.Find().ToList();
// .. rest snipped.
}
Хорошо ... пока мы сейчаспопросить некоторые службы найти все продукты и затем перечислить их.Kewl.Тем не менее, нам все равно, откуда эти продукты.Или даже, что это Product Service
.Это ключ -> Мы оставляем DI / IoC беспокоиться об этом .Все, что нас волнует, это тот факт, что у нас есть ProductService
, который делает некоторые вещи с некоторыми продуктами.В этом случае он собирается Find
всех продуктов, а затем мы просим его перечислить все найденные продукты.
Так, где DI / IoC вступает в игру?
ЭтоВолшебная часть единорога:)
Когда этот контроллер был инстанцирован , он спросил StructureMap:
"Oi! StructureMap! Мне нужно создать HomeController.Но у HomeController есть по крайней мере один конструктор ... и самый сложный конструктор, который у него есть (примечание: DI / IoC называет это самым жадным конструктором ), перечисляет ряд объектов, которые ему требуются. Итак ... Iнужно сначала создать эти объекты, затем создать мой HomeController .. и передать эти объекты в. передать эти объекты в.
Давайте посмотрим на код ...
public class HomeController : Controller
{
private IProductService _productService;
private ILoggingService _loggingService;
public HomeController(IProductService productService, ILoggingService loggingService)
{
_productService = productService;
_loggingService = loggingService;
}
public ActionMethod Index()
{
var products = _productService.Find().ToList();
// rest snipped.
}
}
Вау - здесь происходит несколько вещей. Давайте вспомним -> Итак, StructureMap говорит:
Мне нужен экземпляр IProductService
и ILoggingService
.., которые я передаю HomeControllerконструктор ... ты можешь дать мне это, пожалуйста? "
И StructureMap тогда говорит:
Хорошо .. сначала -> IProductService.Давайте посмотрим здесь, вы сопоставили IProductService с вашим пользовательским классом, названным ReallyFastProductService
.Кьюл, я создам одного из тех плохих парней.Далее, вы сопоставили ILoggingService с классом NLogLoggingService
... приятно!NLog Wroxs, чувак.Так что я тоже создам одного из тех плохих парней.Хорошо, теперь я сделал эти два экземпляра.В заключение!Теперь я могу создать экземпляр HomeController, который вам нужен ... и затем я передам эти два объекта, которые я только что создал, в конструктор HomeController ... и альт!вот экземпляр Controller.
... так что теперь у вас есть экземпляр Controller.
.... и когда вы входите в метод Index (), если вы используетемышь и наведите курсор мыши на экземпляры, они будут ReallyFastProductService
и NLogLoggingService
.
Отлично!Таким образом, это означает, что метод Index()
никогда не тесно связан с конкретной реализацией класса.
Теперь вы решили, что вам не нравится весь код, который вы делали вReallyFastProductService
и решил написать еще один, который использует некоторые новые уловки и навыки, которые вы только что приобрели.Итак, теперь вы делаете второй класс с именем PewPewProductService
, потому что он pwns.Теперь, если вы измените отображение StructureMap с ...
ObjectFactory.Configure(x =>
{ x.For<IProductService>().Add(new ReallyFastProductService());});
на
ObjectFactory.Configure(x =>
{ x.For<IProductService>().Add(new PewPewProductService());});
... внезапно, все методы в этом HomeController теперь ссылаются на логику в новомкласс вы только что построили.Нет необходимости изменять какой-либо код в контроллере.
Поймайте пенни, когда она упадет:)
Добро пожаловать в DI / IoC и почему он пинает серьезный приклад.*