好的,
我确信Jeremy Miller 会更正我的帖子并告诉你真实情况,但是使用StructureMap 创建控制器的自定义Controller factory 的想法是因为Controller class 是key class 大部分逻辑开始并发生的地方(是的,之前发生过动作过滤器和其他东西,但让我们保持简单) - 这需要预先拥有所有依赖项-在任何逻辑开始之前设置。
所以想法是这样的。如果所有的逻辑和魔法独角兽的东西都发生在Controllers 方法中,那么当我们第一次进入该方法时......我们需要已经设置了所有需求。更重要的是,任何控制器中的每个方法都不应该关心它有什么要求(即实例) .. 只是某个人,来自某个地方。 .. 已经做出了这个决定,并给了我我们可能需要的所有重要物品。
这是 DI/IoC 的核心。
所以让我们用一些非常简单的代码来解释这一点,因为我不擅长解释。
假设我们在控制器中有以下方法:-
public ActionMethod Index()
{
// List all Products.
}
很简单。只是向浏览器列出一些产品。所以你需要问的第一件事是 -> Products 是什么?他们来自哪里?好吧,控制器方法根本不问这个问题。事实上,它并不关心他们来自哪里。它只关心它有 something 是 Product。
所以当我们采用这种方法时,我们也不应该关心产品信息存在于何处。我们只是想用这个叫做Products'的东西做点什么。
好的..让我们用它做点什么...
public ActionMethod Index()
{
var products = _myProductService.Find().ToList();
// .. rest snipped.
}
好的 .. 到目前为止,我们现在要求一些服务来查找所有产品,然后列出它们。科尔。尽管如此,我们并不关心这些产品的来源。甚至,这是什么Product Service。这是关键 -> 我们让 DI/IoC 来担心这个。我们所关心的是我们有一些ProductService 对一些产品做一些事情。在这种情况下,它会去Find所有产品,然后我们要求它列出所有找到的产品。
那么 DI/IoC 在哪里发挥作用?
这是独角兽魔法部分:)
当这个控制器被实例化时,它询问了 StructureMap:
“Oi!StructureMap!我需要创建一个
家庭控制器。但是 HomeController
至少有一个构造函数..和
它拥有的最复杂的构造函数(注意:
DI/IoC 称之为最贪婪
构造函数) 列出了一些
它需要的对象。所以我
需要先创建这些对象,
然后创建我的 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。 Kewl,我会创造一个坏男孩。
接下来,您已将 ILoggingService 映射到 NLogLoggingService 类...很好!
NLog wroxs,伙计。所以我也会创造一个坏男孩。好的,我现在已经制作了这两个实例。
最后!我现在可以创建您所追求的 HomeController 的实例..
然后我将把我刚刚制作的这两个对象传递给 HomeController 构造函数......和中提琴!这是控制器实例。
...所以现在,你有了控制器实例。
....当您进入 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 中的所有方法现在都引用了您刚刚构建的新类中的逻辑。无需更改Controller中的任何代码。
抓住落下的一分钱 :)
欢迎来到 DI/IoC 以及它为何如此重要。