控制反转& .NET Framework中的依赖注入

时间:2010-07-20 19:49:49

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

是否有任何特定的DI示例/实例作为.NET Framework本身的架构原则或设计模式 ?框架/ BCL中的任何(或许多)类型是否符合IoC?

基于C#的类型名称和简要说明/解释会很棒!

这将使得DI注入设计原则成为最佳实践的必要性......因为它是从基础框架本身收集的。

我重申,我不是在为框架中的IoC / DI IN 寻找IoC / DI框架

编辑:只是想获得更多实例/示例...因此赏金!

6 个答案:

答案 0 :(得分:16)

答案 1 :(得分:12)

StreamReader和StreamWriter都可以看作是IoC / DI的例子。

每个允许您分别注入不同的Stream对象(或其衍生物之一)进行读/写。

FileInfo fi = new FileInfo(@"C:\MyFile.dat");
StreamWriter sw = new StreamWriter(fi.Open());

或者:

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);

两者都允许:

sw.Write("Hello world!");

同样的方式,无论你在构造函数的调用中注入了什么类型的流。

答案 2 :(得分:5)

当然 - IServiceProvider接口自1.0起就成为了Framework的一部分。这不是DI,因为它通常在这里讨论(使用“内核”),但它是IoC使用服务定位器模式。

如果您深入研究任何Windows窗体设计器代码,您会看到它充满了像这样的行:

IDesignerOptionService service = 
    (IDesignerOptionService)this.GetService(typeof(IDesignerOptionService));

如果您正在使用Component,那么您可以通过Site媒体获取此权限。在创建自定义控件时,这是非常常见且实际需要的知识。

这是服务地点,教科书示例。您有一个通用的IServiceProvider,可以按服务类型分发您请求的抽象服务。如果您想创建自定义设计器 - 智能标签等 - 那么您需要了解所有这些。它与ASP.NET类似。


<子> P.S。请不要在新代码中使用 IServiceProvider。这是一个非常古老的非通用接口。如果要创建需要IoC容器才能工作的可重用库,则应使用Common Service Locator代替。但是,除非您绝对要求您的库与应用程序层使用的DI库无关,否则不要使用 ;大多数特定于实现的容器/内核提供了更多更丰富的API,如果您将自己定位于CSL,则会错过这些API。

答案 3 :(得分:4)

这是一个如何在.NET 4中创建System.ComponentModel.Composition.Hosting.CompositionContainer的示例:

var exeCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var dircatalog = new DirectoryCatalog(".");
var aggregateCatalog = new AggregateCatalog(exeCatalog, dirCatalog);
var exportProvider = new CatalogExportProvider(aggregateCatalog);
var container = new CompositionContainer(exportProvider);

这是通过构造函数参数进行依赖注入的示例。因为遵循了依赖注入模式,所以这些类是非常可扩展的:您可以编写自己的ComposablePartCatalog实现并将其传递给导出提供程序构造函数。或者您可以绕过零件目录的整个概念并编写自己的ExportProvider实现。

(顺便说一下,CompostionContainer本身就是IoC框架的一部分,但这不是本例的重点。)

答案 4 :(得分:3)

答案 5 :(得分:2)

我目前正在阅读Roy Osherove撰写的书The Art of Unit Testing。他提到了一种称为 Extract and Overload 的技术(即通过覆盖负责返回依赖关系的虚方法将依赖注入类中。)

我想我遇到过这种技术的各种情况,例如:

  • 自定义ADO.NET类型DataTable
    如果您派生自DataTable,则可以覆盖各种方法,例如GetRowType()CreateInstance()和其他方法。

  • 自定义Workflow Foundation活动设计器(在.NET 3.5中)
    我不记得确切的类,但我认为如果你想创建自定义活动设计,你从现有的类中派生出新的类,模式大致相同;您覆盖一个虚拟方法,该方法允许您将自定义依赖项返回到框架。