StructureMap 2.6.1和ASP.NET MVC 2问题(来自DI的完整初学者)

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,以及它为什么会引起严重的屁股.

在此输入图像描述

  • 是的 - > TekPub有一个关于DI/IoC的免费视频:: http://tekpub.com/view/concepts/1 (2认同)