Gup*_*R4c 1 structuremap asp.net-mvc dependency-injection repository-pattern
在另一个线程上与@Aaronaught的对话中,我已经开始将我的应用程序转换为使用依赖注入和存储库模式,但我有点卡住了.我想我得到了模式的大部分内容和流程,但我坚持将StructMap实现到ASP.NET MVC 2.我读过的例子似乎已经过时了,我最新版本的Structure Map是我的使用(2.6.1).
我希望有人可以根据我粘贴的代码填补空白:
public static class Bootstrapper {
public static void Configure() {
ObjectFactory.Configure(x => {
x.For<DataContext>().Add(new DataContext());
});
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,我可以从我的控制器中获取DataContext的实例:
protected DataContext dc = ObjectFactory.GetInstance<DataContext>();
Run Code Online (Sandbox Code Playgroud)
我知道做错了,但我对如何避免它感到困惑.继续,这是控制器工厂:
public class StructureMapControllerFactory : DefaultControllerFactory {
protected override IController GetControllerInstance(
RequestContext rc,
Type ct) {
return (ObjectFactory.GetInstance(ct) as Controller);
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白这究竟是什么,但它在示例中,所以我正在复制它.有人可以向我解释一下吗?
现在从我的理解,应该是注册表,如果我理解正确,全局化对象实例,如DataContext.那是对的吗?如果是这样,我该如何为StructureMap 2.6.1编写注册表?我看到的示例代码似乎已经过时,因为当我编写它时,我没有相同的选项(通过IntelliSense),所以我不确定如何编写它...
我将非常感谢您填写我所拥有的空白.
PS我对依赖注入和存储库的经验总共约8小时.
UPDATE /结论
阅读下面的@ Pure的优秀解释并观看他在子评论中引用的tekpub视频,我选择了Ninject而不是StructureMap.
我不知道Ninject是否比StructureMap更好,但从我的观点来看,开始并开始变得更容易.
Pur*_*ome 10
好,
我敢肯定,杰里米米勒会纠正我的职务,给你真正的真理,而是具有定制的理念Controller factory,它使用StructureMap创建的控制器,是因为Controller class是重点班,其中大部分逻辑揭开序幕,并发生(是的,有动作过滤器和之前发生的事情,但让我们保持这个简单) - 这需要在任何逻辑开始之前预先设置所有依赖项.
所以这个想法就是这样.如果所有的逻辑和魔法独角兽的东西都发生在Controllers方法中,那么当我们第一次进入方法时......我们需要设置所有的需求.更重要的是,任何控制器中的每个方法都不应该关心它有什么要求(即实例) ......只是某个人,来自某个地方...已经做出了这个决定,并给了我所有可能需要的重要对象.
这是DI/IoC的核心所在.
所以让我们用一些非常简单的代码来解释这个,因为我不善于解释事情.
假设我们在Controller中有以下方法: -
public ActionMethod Index()
{
// List all Products.
}
Run Code Online (Sandbox Code Playgroud)
很简单.只需在浏览器中列出一些产品即可.所以你首先需要问的是 - >是什么Products?他们来自哪里?好吧,控制器方法根本不问这个问题.事实上,它并不关心他们来自哪里.它只关心它有什么这是一个Product.
因此,当我们使用这种方法时,我们也不应该关心产品信息的存在位置.我们只是想用这个名为Products'的东西做点什么.
好的..所以让我们做点什么......
public ActionMethod Index()
{
var products = _myProductService.Find().ToList();
// .. rest snipped.
}
Run Code Online (Sandbox Code Playgroud)
好的..到目前为止,我们现在要求一些服务找到所有产品,然后列出它们.KEWL.不过,我们并不关心这些产品的来源.甚至,这是什么Product Service.这是关键 - > 我们让DI/IoC担心这一点.我们所关心的是我们有ProductService一些东西可以用一些产品做一些事情.在这种情况下,它将转到Find所有产品,然后我们要求它列出找到的所有产品.
那么DI/IoC在哪里发挥作用?
这是独角兽魔法部分:)
当这个控制器实例化时,它询问了StructureMap:
"Oi!StructureMap!我需要创建一个HomeController.但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.
}
}
Run Code Online (Sandbox Code Playgroud)
哇 - 这里发生了一些事情.让我们回顾一下 - >所以StructureMap说:
我需要一个a
IProductService和a的实例ILoggingService,我将它传递给HomeController构造函数......你能给我那些请的吗?"
然后StructureMap说:
好的..首先 - >一个IProductService.让我们看到这里,你已经将IProductService映射到你所做的自定义类,称为
ReallyFastProductService.凯尔,我会创造一个坏男孩.接下来,你已经将ILoggingService映射到了一个NLogLoggingService类......很好!NLog wroxs,老兄.所以我也会创造一个坏男孩.好的,我现在已经完成了这两个实例.最后!我现在可以创建一个你正在使用的HomeController的实例..然后我将把我刚制作的那两个对象传递给HomeController构造函数......并且中提琴!这是Controller实例.
...所以现在,你有了Controller实例.
....当你进入Index()方法时,如果你使用鼠标并将鼠标悬停在实例上,它们将是a ReallyFastProductService和a NLogLoggingService.
真棒!所以这意味着该Index()方法永远不会紧密耦合到类的特定实现.
现在,你决定你不喜欢你所做的所有代码,ReallyFastProductService并决定编写另一个代码,这需要使用你刚刚选择的一些新技巧和技巧.所以现在你做了一个名为的第二课PewPewProductService,因为它是pwns.现在,如果你改变你的StructureMap映射...
ObjectFactory.Configure(x =>
{ x.For<IProductService>().Add(new ReallyFastProductService());});
Run Code Online (Sandbox Code Playgroud)
至
ObjectFactory.Configure(x =>
{ x.For<IProductService>().Add(new PewPewProductService());});
Run Code Online (Sandbox Code Playgroud)
...突然之间,HomeController中的所有方法现在都引用了刚刚构建的新类中的逻辑.无需更改Controller中的任何代码.
随着它下降抓住便士:)
欢迎来到DI/IoC,以及它为什么会引起严重的屁股.
