DI and IOC examples in simple C#
Possible Duplicate:
Inversion of Control < Dependency Injection
有人能帮我用简单的C例子来理解DI和IOC吗?正如我所理解的,ioc是控制流的反转(对我来说没有什么意义),di是通过属性或构造函数注入接口。不知道这两个是如何相关的。
谢谢您。
假设您有一个需要服务的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class A { IEmailSender _emailSender public A(IEmailSender emailSender) { _emailSender = emailSender; } private void SendEmail() { _emailSender.Send(); } } |
现在,A类对IMALSENDER有依赖性,这意味着它需要一个实现IMALSENDER的对象来执行它的函数。
一个依赖注入框架,如NICATION或AutoFAC将负责创建一个对象,实现IMALSENDER并将其注入到A的构造函数中,前提是您告诉他们如何创建这样的对象。
使用NIXECT:
1 | Bind<IEmailSender>().To<EmailSender>(); |
这告诉ninject,每当类需要iemailsender时,就给它们emailsender(当然假定emailsender实现iemailsender接口)。
这是我能想到的最简单的,希望这能有所帮助。
我强烈建议您阅读.NET书籍中的依赖项注入,它用全面的代码示例详细描述了所有方面。关于控制反转,您应该参考罗伯特·马丁的另一本书:C语言中的敏捷原则、模式和实践。它详细描述了坚实的原则,并给出了实例和可理解的解释。这两本书真的帮助我理解了这些原则。
我会补充一个我已经被告知的解释。
正如您正确指出的,依赖注入是一个类通过构造函数或setter注入来要求其合作者的行为。您可以将其视为一种编码技术。另一方面,控制反转更多的是一种设计技巧——一种哲学,如果你愿意的话。
在过程编程(以及OO语言中的过程式编程)中,您通常具有某种"命令和控制"哲学。如果要创建一个由三个楼层对象组成的房屋对象,每个楼层对象由若干个房间对象组成,则创建一个房屋对象,其构造函数实例化三个楼层对象,而每个楼层对象的构造函数依次实例化房间对象。
当你反转控制时,你是在反转命令和控制范式。有了国际奥委会,当我去实例化一座房子时,它不会为我处理所有的细节。相反,它说,通过它的构造函数(和依赖注入),"没有某些层,你不能实例化我"。所以,你去例示一下地板,他们说"不,不是没有房间"。现在,在这种"倒转"的风格中,我们的房子不控制房间的创建,而是由其他人来决定,它只表达了它对给定房间的作用。这是可取的,因为通过在命令头上翻转命令和控件,您可以有更好的接口来推理和测试代码——更容易将事物解构成组件。
综上所述,控制反转是一种哲学,依赖注入是实现控制反转的手段。
国际奥委会是国际奥委会。控制反转意味着交换谁决定如何完成任务。
在旧世界中,您可以创建一个名为logger的类和一个名为logtime()的类中的方法。它的唯一目的是将当前时间写入一个文件。
1 2 3 4 | public void LogTime() { WriteToFile(GetCurrentTime()); } |
在这里,类有一个名为writeToFile和getCurrentTime的方法。IOC只是意味着,与其让logger类决定如何写入文件,甚至获取当前时间,还不如让外部提供者提供这些细节。
这就是迪进来的地方。你注入了依赖。该方法依赖于写入文件并获取当前时间的方法。你注入那些方法。
DI有两种常见的模式,即属性注入和构造函数注入。他们在罐头里说什么就做什么。如何进行注入取决于特定的框架。
有些使用属性,有些使用配置文件。有些人采取了最佳猜测方法。
沿着DI,您有SL(服务位置),这就像礼貌的DI。在DI中,你说"接受这种依赖并喜欢它"。有了sl,上面的logger类会说"有什么东西可以满足这种依赖性吗?"?"看到了吗?彬彬有礼。
使其工作的核心是接口。logtofile可以是ilogsofiles接口上的方法。然后,您可以有六个不同的接口实现,并注入最合适的。
有很多框架可以为您管理所有这些,但是一个简单的servicelocator是10行代码,一个简单的DI可能不超过这个的两倍。不过,你很快就会开始想要额外的。看看Ninject。我推荐它纯粹是因为它小而简单,可能是一个好的起点。