ASP.NET MVC3手动编码IoC

时间:2012-01-27 21:46:35

标签: c# asp.net-mvc-3 dependency-injection inversion-of-control

Ninject,Sprint.NET,Unity,Autofac,Castle.Windsor都是IoC框架可用的例子。但是,我喜欢写自己的学习曲线和控制。通常的做法是不要“重新发明轮子”,只使用预先存在的结构。如果您的评论符合这些标准,请保持温和。

可以在不使用XML的情况下实施IoC吗?在我看来,大多数(如果不是全部)上述框架都使用XML,但我更愿意用C#编写我的,而不是使用XML来加载.dll。无论如何,C#最终都被转换成了一个.dll。

根据我的理解,如果错误请更正,IoC可以与DI一起使用,使类的功能基于其定义和实现,同时允许分离关注点。

这是在C#中使用microsoft的库System.ComponentModel.IContainer通过拥有一个继承它的类来完成的。类(如Product)将具有接口IProduct。然后,通用构造函数将继承IContainer并在构造函数中,允许传入存储库,传入实例化对象以及传入的函数。这将允许控制器操作然后实例化接口(IProduct) ),使用当前存储库实例实例化通用构造函数,然后将接口和函数传递给它。

此设置准确吗?

我仍在尝试了解有关此主题的更多信息,并阅读了有关IoC,DI的wiki文章,并阅读了有关Castle.Windsor,ninject,Unity的文章,并查看了MSDN中有关使用的C#库的多个定义。非常感谢任何帮助,更正或建议。感谢

3 个答案:

答案 0 :(得分:8)

  

可以在不使用XML的情况下实施IoC吗?

是的,可以在不使用任何XML的情况下配置Ninject,Unity,Castle Windsor和Autofac。 (不确定Spring.NET,上次我用它是不可能的,版本1.3)

  

从我的理解,如果错误请更正,IoC可以使用   DI使类的功能基于他们的   定义和实施,同时允许分离   顾虑。

如果在“IoC”下你的意思是“IoC容器”然后是,它可以用于DI,但由于DI是Inversion Of Control的一个特例,你的IoC容器只是你依赖的容器。只要拥有它你就不会神奇地获得任何对DI友好的类型。它只是支持管理反向依赖项。

修改

由于 Mystere Man 在他的回答中指出,您需要提高对IoC容器的理解。因此,我建议您阅读wonderful book(来自Mark Seeman)关于所有内容的内容。

答案 1 :(得分:5)

我认为没有DI容器就可以开始了。在专注于使用DI框架之前,请关注最佳模式和实践。特别是,围绕依赖注入设计所有类,并确保您的代码遵循SOLID原则。这两种听起来都很简单,但是在你做到这一点之前,这需要转变思维方式和大量练习(但非常值得)。

当您这样做并且做得好时,您会很快发现您的应用程序将以惊人的方式发展。您的代码将以您以前从未想象过的方式进行测试和扩展,而不会使代码随着时间的推移而腐烂(但是,它始终关注以防止代码腐烂)。

然而,当你做到这一切时(这需要很多练习),你仍然会有一部分应用程序,尽管你付出了最大的努力,但仍会变得更加复杂和难以维护,应用程序增长这是将所有依赖项连接在一起的应用程序的一部分:Composition Root

这就是DI容器的用武之地。它们有着名字,并且在功能上相互竞争,但是它们的目标可以用一句话来表达:

  

DI容器的目标是保持Composition Root   可维护性。

虽然您可以编写自己的简单DI容器来连接您的依赖项,但是为了防止您的Composition Root成为一个非常脆弱,不断变化的泥球,容器必须至少有一个关键特性:自动构造函数注入(aka自动布线)。通过自动连接,容器将查看它需要创建的类型的构造函数参数,并将根据这些参数的类型在其中注入依赖项。此功能将使维护噩梦和健康的组合根之间产生差异。虽然创建自己的容器支持自动连接并不是那么难(使用表达式树需要大约20行代码),但是开始需要自动连接的那一刻就是开始使用现有DI框架的时候了。 / p>

总而言之,如果您觉得通过手工操作可以帮助您学习,只要您坚持使用SOLID,DI,DRY和TDD即可。如果为应用程序中的每个更改更改组合根目录的负担太大(这将比您预期的更快),请切换到已建立的框架。

答案 2 :(得分:2)

我建议首先使用现有的DI容器,从最终用户的角度理解它是如何工作的。然后你可以重新设计轮子。我最喜欢的一句话是“你必须先知道规则才能打破它们。”

你所说的一些内容并没有多大意义。你不必在我知道的任何框架中使用System.ComponentModel.IContainer。也许Unity要求(微软的容器),但其他人都没有。我不熟悉Unity thogh。