简体   繁体   English

.NET框架中的控制和依赖注入反转

[英]Inversion of Control & Dependency Injection in the .NET Framework

Is there any specific example/instance of DI being applied as an architectural principle or design pattern in the .NET Framework itself ? 在.NET Framework本身中,是否有任何将DI用作架构原理或设计模式的特定示例/实例? Do any (or many) of the types in the framework/BCL conform to IoC? 框架/ BCL中的任何(或许多)类型是否符合IoC?

The type names and a brief illustration/explanation based in C# would be great! 类型名称和基于C#的简短插图/说明都很棒!

This would compund the need for DI infused design principle as a best-practice...as it is gleaned from the base framework itself. 最好将DI注入设计原则作为最佳实践……因为它是从基础框架本身收集而来的。

I reiterate, I am not looking for IoC/DI Frameworks BUT for IoC/DI IN the framework. 我重申,我不是在寻找的IoC / DI框架 IOC / DI框架

EDIT: Just wanted to get more instances/examples ... hence the bounty! 编辑:只是想获得更多的实例/示例...因此赏金!

In general there aren't a lot of examples of DI in the BCL - perhaps because the BCL is a rather self-contained framework, and DI is more of an application architecture concern... However, here are some examples I've been able to find so far. 通常,BCL中没有很多DI的示例-也许是因为BCL是一个相当独立的框架,而DI则更多地是与应用程序体系结构有关的。但是,这里有些示例我能够找到到目前为止。

Constructor Injection 构造函数注入

There are not many examples of Constructor Injection in the BCL. BCL中没有很多构造函数注入的示例。 The best candidates are 最好的候选人是

  • System.IO.StreamWriter System.IO.StreamWriter
  • System.IO.StreamReader System.IO.StreamReader

Property Injection 资产注入

  • System.ComponentModel.IComponent.Site System.ComponentModel.IComponent.Site

We also see a variation in Workflow Foundation's WorkflowRuntime.AddService and related methods, although you might argue that this is closer to Method Injection. 我们还看到Workflow Foundation的WorkflowRuntime.AddService和相关方法的变体,尽管您可能会认为这更接近于方法注入。

Method Injection 方法注入

  • System.ComponentModel.Design.IDesigner.Initialize System.ComponentModel.Design.IDesigner.Initialize
  • System.ComponentModel.TypeConverter (many methods take ITypeDescriptorContext) System.ComponentModel.TypeConverter(许多方法采用ITypeDescriptorContext)
  • System.Web.Mvc.IModelBinder.BindModel (from ASP.NET MVC) System.Web.Mvc.IModelBinder.BindModel(来自ASP.NET MVC)

Ambient Context 环境语境

  • System.Threading.Thread.CurrentPrincipal System.Threading.Thread.CurrentPrincipal
  • System.Threading.Thread.CurrentCulture System.Threading.Thread.CurrentCulture
  • System.Threading.Thread.CurrentUICulture System.Threading.Thread.CurrentUICulture
  • System.Diagnostics.Trace.Listeners System.Diagnostics.Trace.Listeners

FWIW, I drew these examples from my upcoming book . FWIW,我从即将出版的书中借鉴了这些例子。

Both the StreamReader and StreamWriter could be seen as examples of IoC/DI. StreamReader和StreamWriter都可以视为IoC / DI的示例。

Each allow you to inject a different Stream object (or one of its derivatives) for reading/writing respectively. 每个对象都允许您注入不同的Stream对象(或其派生对象之一)以分别进行读取/写入。

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

Or: 要么:

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

Would both allow: 两者都允许:

sw.Write("Hello world!");

The same way, no matter what kind of Stream you injected in the call to the constructor. 相同的方式,无论您在对构造函数的调用中注入了哪种Stream。

Sure - the IServiceProvider interface has been part of the Framework since 1.0. 当然-从1.0开始, IServiceProvider接口已成为框架的一部分。 This isn't DI as it is typically discussed here (using a "kernel"), but it is IoC using the Service Locator pattern. 这不是DI,因为这里通常会讨论它(使用“内核”),但是使用Service Locator模式是IoC。

If you dig into any of the Windows Forms Designer code, you'll see it peppered liberally with lines like this one: 如果您深入研究Windows Forms Designer的任何代码,就会发现该代码中包含如下代码:

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

If you're working with a Component , then you get access to this via the Site property. 如果您正在使用Component ,那么您可以通过Site属性来访问它。 It's quite common and practically required knowledge when creating custom controls. 在创建自定义控件时,这是相当普遍且实际需要的知识。

This is Service Location, textbook example. 这是服务位置,教科书示例。 You've got a generic IServiceProvider that hands out abstract services you request by service type. 您有一个通用的IServiceProvider ,可以按服务类型IServiceProvider您请求的抽象服务。 If you ever want to create custom designers - smart tags and so on - then you need to know all of this. 如果您想创建自定义设计器-智能标记等-那么您需要了解所有这些。 It's similar for ASP.NET as well. ASP.NET也是如此。


PS Please don't use IServiceProvider in new code. PS:请勿在新代码中使用 IServiceProvider It's a very old, non-generic interface. 这是一个非常古老的非通用接口。 If you are creating reusable libraries that require an IoC container in order to work, you should use the Common Service Locator instead. 如果要创建需要IoC容器才能工作的可重用库,则应改用Common Service Locator But don't even use that unless you absolutely require that your library be agnostic of the DI library used at the application tier; 但是除非您绝对要求您的库与应用程序层使用的DI库无关否则甚至不要使用 most of the implementation-specific containers/kernels offer much richer APIs that you'll miss out on if you nail yourself to the CSL. 大多数特定于实现的容器/内核都提供了更丰富的API,如果您将自己牢牢掌握在CSL上,就会错过它们。

This is an example of how you can create a System.ComponentModel.Composition.Hosting.CompositionContainer in .NET 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);

This is an example of dependency injection via constructor arguments. 这是通过构造函数参数进行依赖项注入的示例。 Because the dependency injection pattern was followed, these classes are very extensible: you can write your own ComposablePartCatalog implementation and pass that to the export provider constructor. 因为遵循了依赖项注入模式,所以这些类非常可扩展:您可以编写自己的ComposablePartCatalog实现,并将其传递给导出提供程序构造函数。 Or you can bypass the whole concept of part catalogs and write your own ExportProvider implementation. 或者,您可以绕过零件目录的整个概念,并编写自己的ExportProvider实现。

(Incidentally, CompostionContainer is itself part of an IoC framework, but that's not the point of this example.) (顺便说一句, CompostionContainer本身就是IoC框架的一部分,但这不是本示例的重点。)

.NET, especially in a web context, offers Providers to define alternative implementations of framework components. .NET(尤其是在Web环境中)提供了提供程序,以定义框架组件的替代实现。 The framework defines an abstract base class, defines one or two concrete implementations on top of it, and allows users to provide their own implementations where desired. 该框架定义了一个抽象基类,在其之上定义了一个或两个具体实现,并允许用户在需要的地方提供自己的实现。

Once defined, the user doesn't control the life-cycle of their implementation. 定义后,用户将无法控制其实现的生命周期。 The framework takes over and manages instantiation, setup, and disposal. 该框架接管并管理实例化,设置和处置。

Start with System.Configuration.Provider.ProviderBase . System.Configuration.Provider.ProviderBase开始。

.NET classes that implement ProviderBase: 实现ProviderBase的.NET类:

  • System.Configuration.ProtectedConfigurationProvider - encrypting and decrypting protected-configuration data System.Configuration.ProtectedConfigurationProvider-加密和解密受保护的配置数据
    • System.Configuration.DpapiProtectedConfigurationProvider (concrete) System.Configuration.DpapiProtectedConfigurationProvider(具体)
    • System.Configuration.RsaProtectedConfigurationProvider (concrete) System.Configuration.RsaProtectedConfigurationProvider(具体)
  • System.Configuration.SettingsProvider - custom settings in the application settings architecture System.Configuration.SettingsProvider-应用程序设置体系结构中的自定义设置
    • System.Configuration.LocalFileSettingsProvider (concrete) System.Configuration.LocalFileSettingsProvider(具体)
    • System.Web.Profile.ProfileProvider System.Web.Profile.ProfileProvider
      • System.Web.Profile.SqlProfileProvider (concrete) System.Web.Profile.SqlProfileProvider(具体)
  • System.Web.Management.WebEventProvider - customize the ASP.NET health-event processing System.Web.Management.WebEventProvider-自定义ASP.NET健康事件处理
    • System.Web.Management.BufferedWebEventProvider System.Web.Management.BufferedWebEventProvider
      • System.Web.Management.MailWebEventProvider System.Web.Management.MailWebEventProvider
        • System.Web.Management.SimpleMailWebEventProvider (concrete) System.Web.Management.SimpleMailWebEventProvider(具体)
        • System.Web.Management.TemplatedMailWebEventProvider (concrete) System.Web.Management.TemplatedMailWebEventProvider(具体)
      • System.Web.Management.SqlWebEventProvider (concrete) System.Web.Management.SqlWebEventProvider(具体)
    • System.Web.Management.EventLogWebEventProvider (concrete) System.Web.Management.EventLogWebEventProvider(具体)
    • System.Web.Management.IisTraceWebEventProvider (concrete) System.Web.Management.IisTraceWebEventProvider(具体)
    • System.Web.Management.TraceWebEventProvider (concrete) System.Web.Management.TraceWebEventProvider(具体)
    • System.Web.Management.WmiWebEventProvider (concrete) System.Web.Management.WmiWebEventProvider(具体)
  • System.Web.Security.MembershipProvider - custom membership for membership services System.Web.Security.MembershipProvider-成员资格服务的自定义成员资格
    • System.Web.Security.ActiveDirectoryMembershipProvider (concrete) System.Web.Security.ActiveDirectoryMembershipProvider(具体)
    • System.Web.Security.SqlMembershipProvider (concrete) System.Web.Security.SqlMembershipProvider(具体)
  • System.Web.Security.RoleProvider - custom role-management for role-management services System.Web.Security.RoleProvider-角色管理服务的自定义角色管理
    • System.Web.Security.AuthorizationStoreRoleProvider (concrete) System.Web.Security.AuthorizationStoreRoleProvider(具体)
    • System.Web.Security.SqlRoleProvider (concrete) System.Web.Security.SqlRoleProvider(具体)
    • System.Web.Security.WindowsTokenRoleProvider (concrete) System.Web.Security.WindowsTokenRoleProvider(具体)
  • System.Web.SessionState.SessionStateStoreProviderBase - session-state data stores System.Web.SessionState.SessionStateStoreProviderBase-会话状态数据存储
    • System.Web.SessionState.InProcSessionStateStore (concrete) System.Web.SessionState.InProcSessionStateStore(具体)
    • System.Web.SessionState.OutOfProcSessionStateStore (concrete) System.Web.SessionState.OutOfProcSessionStateStore(具体)
    • System.Web.SessionState.SqlSessionStateStore (concrete) System.Web.SessionState.SqlSessionStateStore(具体)
  • System.Web.SiteMapProvider - custom SiteMap persistent data store System.Web.SiteMapProvider-自定义SiteMap持久数据存储
    • System.Web.StaticSiteMapProvider System.Web.StaticSiteMapProvider
      • System.Web.XmlSiteMapProvider (concrete) System.Web.XmlSiteMapProvider(具体)
  • System.Web.UI.WebControls.WebParts.PersonalizationProvider - loads and stores personalization data on behalf of a WebPartPersonalization instance System.Web.UI.WebControls.WebParts.PersonalizationProvider-代表WebPartPersonalization实例加载和存储个性化数据
    • System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider (concrete) System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider(具体)

Examples: 例子:

I am currently reading the book The Art of Unit Testing by Roy Osherove. 我目前正在阅读Roy Osherove 的《单元测试的艺术 》一书。 He mentions a technique called Extract and Overload (that is, injecting a dependency into a class through overriding a virtual method that is responsible for returning the dependency). 他提到了一种称为“ 提取并重载”的技术(即,通过覆盖负责返回依赖关系的虚拟方法,将依赖关系注入到类中)。

I think I've come across various instances of that technique, for example these: 我想我遇到过该技术的各种实例,例如:

  • Customizing the ADO.NET type DataTable : 自定义ADO.NET类型DataTable
    If you derive from DataTable , you have the possibility of overriding various methods, such as GetRowType() , CreateInstance() , and others. 如果从DataTable派生,则可以覆盖各种方法,例如GetRowType()CreateInstance()和其他方法。

  • Customizing Workflow Foundation Activity designers (in .NET 3.5) 自定义Workflow Foundation Activity设计器(在.NET 3.5中)
    I don't remember the exact class, but I think if you want to create custom activity designs, you derive new classes from existing ones, and the pattern is much the same; 我不记得确切的类,但是我想如果您想创建自定义活动设计,则可以从现有的类中派生出新的类,并且模式大体相同。 you override a virtual method which allows you to return your custom dependency to the framework. 您重写了一个虚拟方法,该方法允许您将自定义依赖项返回到框架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 理解控制和依赖注入的反转 - Understanding Inversion of Control and Dependency Injection 在尊重控制反转的同时,在 .NET Core 中使用依赖注入 - Usage of Dependency Injection in .NET Core while respecting Inversion of Control 控制/依赖注入的反转,在.net中有很好的解释和示例? - Inversion of Control / Dependency Injection with good explanation and examples in .net? C#MongoDb依赖注入和控制反转 - C# MongoDb Dependency Injection & Inversion of Control 使用IOC(控制反转)进行依赖注入 - Dependency injection using IOC (Inversion of Control) 控制/依赖注入和转换运算符的反转 - Inversion of Control / Dependency Injection and conversion operators ASP.NET Web API中的Castle Windsor / DelegatingHandler / IPrincipal依赖注入(DI)/控制反转(IoC) - Castle Windsor/DelegatingHandler/IPrincipal Dependency Injection (DI)/Inversion of Control (IoC) in ASP.NET Web API .NET Framework类的依赖性反转原则 - The Dependency Inversion Principle with .NET Framework classes uwp 和 c# 和 mvvm 如何做控制反转(依赖注入) - uwp with c# and mvvm how to do inversion of control (dependency injection) 控制反转和依赖注入-我需要您的建议 - Inversion of Control and Dependency Injection - I need your advice
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM