对于ASP.NET MVC,我看到“IoC”和“DI”几乎无处不在。虽然我很清楚...'有点'这些是什么,它是那些几乎模棱两可的,无定形的浮动概念之一,似乎已经过了我,或者我只是没找对地方。随着即将发布的ASP.NET MVC 3.0,我看到了更多。因此,感觉它只是编程的一部分,我只是不知道。
我已经尝试过寻找有关这些主题的书籍,但我发现的大部分内容似乎都做了很多假设(Ruby的历史,了解它是什么但不是如何使用它等)。
我只是提前问清楚。什么 IoC,为什么我关心它?从初学者程序员的角度来看,是否有任何体面的网站覆盖这一点?假设我一无所知。假设我只知道C#。我阅读了关于C#从.NET 1.1到.NET 2.0的所有书籍,博客和教程,当.NET 3.5和LINQ命中时,它变得如此之多,以至于我无法跟上。我是一名从事ASP.NET MVC / C#的新手开发人员,我不禁感到我错过了一些非常重要的东西。 (我对DI(依赖注入)有很多相同的感受)
我用谷歌搜索,我读过博客,我见过Castle.Windsor
,我看过示例代码,我浏览过书籍和网络广播,而且我仍然在黑暗中。感觉就像你知道自己应该知道的工作内部故事之一,但出于某种原因,你没有,而学校并没有真正为我做好准备。
StackOverflow对我来说一直是开发社区中最好的。通过大学和介绍性工作,以及低级自由职业者工作,我将我的编程教育与其他程序员合并(尽管据我所知,这并不是必然会让人感到羞耻)。所以我再一次向社区说明。
咦?我不明白。
与许多试图闯入同一领域的同事交谈时,他们中的许多人都有同样的感受。所以我不禁感到有些不同,我们的“新手”程序员错过了这些编码概念方法的备忘录。我不仅要回答这个问题,而且我认为对于像我这样试图理解它的其他人来说这是一个很好的线索可能是一个聪明的想法(如果存在,则需要更明显)
我发现的一些有用的内容是http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection和http://www.dotnetspark.com/kb/1222-inversion-control--beginner-guide.aspx
但是我仍然在为什么这很重要的问题上摸不着头脑。说实话,我觉得很大一部分开发者社区对IoC和单元测试都有这种感觉。很少列出什么,发现的例子通常很差,或者很难理解。引入.NET时,它是独立的。我不需要一堆其他概念来运行简单的程序。现在,.NET是一种受人尊敬的语言,阳光下的一切都在采用它(nHibernate,MVC,MVP,MVVP,云计算平台,游戏架构等)
(请随时指出我是否只是公然错误。我不是以任何方式称自己'好'。但我知道C#,我非常了解。我认为自己是一个非常快速的学习者因为我有这个困难的时间我只需要假设那里有一些需要填补的'洞'
答案 0 :(得分:12)
让我们暂时搁置所有IoC框架并讨论这个概念。 IoC不是一个新概念,已经存在了很长时间。基本上实现了IoC,使您的系统与某个子系统松散耦合。我们通过将子系统的共同/核心行为提取到合同中来实现解耦。合同通常是界面形状。现在你依赖这个界面。您并不担心特定系统如何具体地为您提供您所追求的行为。
最近我遇到了真实的生活。我们有一个现有的支付系统,然后我们正在开发一个新的支付系统,以坚持PCI。您在这种情况下所做的是在界面中提取两个系统的共同特征,然后您的应用程序仅通过接口与这两个系统进行交互。您可以在配置文件或工厂模式中使用标志,也可以最终在您的应用程序中使用IoC框架注入此依赖项。在运行时,您的应用程序将获得它所依赖的对象。由于任何原因,在任何给定子系统的使用存在不确定性的环境中,您需要DI / IoC。在此示例中,新的支付系统无法按时交付,因此我的应用程序需要一个可配置选项,以便在运行时在任何系统之间切换。如果我不做IoC,每次业务改变主意时我都要做代码更改。
IoC的另一个需求是做TDD。我上面描述的相同内容可用于开发实际应用程序的模拟实现,并可用于在实际组件仍处于开发阶段时进行测试。
Dependency Injection是一本很好的书。您也可以从同一作者here下载关于DI的免费论文。
更新:添加代码以获得更清晰
public interface ITest
{
void Hello();
}
现在我可以有两种不同的具体实现:
public class Hi : ITest
{
public void Hello()
{
HttpContext.Current.Response.Write("Hi there!");
}
}
public class HelloMessage : ITest
{
public void Hello()
{
HttpContext.Current.Response.Write("Hello there!");
}
}
ITest messenger;
if (User Needs "Hi")
{
messenger = new Hi();
}
else if (User Needs "Hello")
{
messenger = new HelloMessage();
}
messenger.Hello();
我的所有应用程序都要调用合同中可用的方法。现在,应用程序正在显式处理依赖项,但没有任何具体的实现。然而,它仍然与这两个具体实现相关联。 IoC框架帮助我们将此作业外包给配置文件。在那里,我可以提供任何其他具体实现,无论它是如何实现的,并且应用程序将继续工作而不需要任何代码更改。
以下是我使用Unity 2并在我自己外包显式处理依赖项的代码。
using (IUnityContainer container = new UnityContainer())
{
container.LoadConfiguration();
ITest messenger = container.Resolve<ITest>();
messenger.Hello();
}
配置相同:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<assembly name="Injection"/>
<container>
<register type="Injection.ITest" mapTo="Injection.Hi"/>
</container>
</unity>
HTH
答案 1 :(得分:2)
对于某些视频介绍,请查看DimeCasts.net。
我喜欢Ioc的两个主要原因:
答案 2 :(得分:1)
答案 3 :(得分:0)
前一段时间我问了类似的问题,在Examples of IoC Containers
处有一些不错的答案答案 4 :(得分:0)