簡體   English   中英

.NET框架中的控制和依賴注入反轉

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

在.NET Framework本身中,是否有任何將DI用作架構原理或設計模式的特定示例/實例? 框架/ BCL中的任何(或許多)類型是否符合IoC?

類型名稱和基於C#的簡短插圖/說明都很棒!

最好將DI注入設計原則作為最佳實踐……因為它是從基礎框架本身收集而來的。

我重申,我不是在尋找的IoC / DI框架 IOC / DI框架

編輯:只是想獲得更多的實例/示例...因此賞金!

通常,BCL中沒有很多DI的示例-也許是因為BCL是一個相當獨立的框架,而DI則更多地是與應用程序體系結構有關的。但是,這里有些示例我能夠找到到目前為止。

構造函數注入

BCL中沒有很多構造函數注入的示例。 最好的候選人是

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

資產注入

  • System.ComponentModel.IComponent.Site

我們還看到Workflow Foundation的WorkflowRuntime.AddService和相關方法的變體,盡管您可能會認為這更接近於方法注入。

方法注入

  • System.ComponentModel.Design.IDesigner.Initialize
  • System.ComponentModel.TypeConverter(許多方法采用ITypeDescriptorContext)
  • System.Web.Mvc.IModelBinder.BindModel(來自ASP.NET MVC)

環境語境

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

FWIW,我從即將出版的書中借鑒了這些例子。

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!");

相同的方式,無論您在對構造函數的調用中注入了哪種Stream。

當然-從1.0開始, IServiceProvider接口已成為框架的一部分。 這不是DI,因為這里通常會討論它(使用“內核”),但是使用Service Locator模式是IoC。

如果您深入研究Windows Forms Designer的任何代碼,就會發現該代碼中包含如下代碼:

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

如果您正在使用Component ,那么您可以通過Site屬性來訪問它。 在創建自定義控件時,這是相當普遍且實際需要的知識。

這是服務位置,教科書示例。 您有一個通用的IServiceProvider ,可以按服務類型IServiceProvider您請求的抽象服務。 如果您想創建自定義設計器-智能標記等-那么您需要了解所有這些。 ASP.NET也是如此。


PS:請勿在新代碼中使用 IServiceProvider 這是一個非常古老的非通用接口。 如果要創建需要IoC容器才能工作的可重用庫,則應改用Common Service Locator 但是除非您絕對要求您的庫與應用程序層使用的DI庫無關否則甚至不要使用 大多數特定於實現的容器/內核都提供了更豐富的API,如果您將自己牢牢掌握在CSL上,就會錯過它們。

這是一個如何在.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框架的一部分,但這不是本示例的重點。)

.NET(尤其是在Web環境中)提供了提供程序,以定義框架組件的替代實現。 該框架定義了一個抽象基類,在其之上定義了一個或兩個具體實現,並允許用戶在需要的地方提供自己的實現。

定義后,用戶將無法控制其實現的生命周期。 該框架接管並管理實例化,設置和處置。

System.Configuration.Provider.ProviderBase開始。

實現ProviderBase的.NET類:

  • System.Configuration.ProtectedConfigurationProvider-加密和解密受保護的配置數據
    • System.Configuration.DpapiProtectedConfigurationProvider(具體)
    • System.Configuration.RsaProtectedConfigurationProvider(具體)
  • System.Configuration.SettingsProvider-應用程序設置體系結構中的自定義設置
    • System.Configuration.LocalFileSettingsProvider(具體)
    • System.Web.Profile.ProfileProvider
      • System.Web.Profile.SqlProfileProvider(具體)
  • System.Web.Management.WebEventProvider-自定義ASP.NET健康事件處理
    • System.Web.Management.BufferedWebEventProvider
      • System.Web.Management.MailWebEventProvider
        • System.Web.Management.SimpleMailWebEventProvider(具體)
        • System.Web.Management.TemplatedMailWebEventProvider(具體)
      • System.Web.Management.SqlWebEventProvider(具體)
    • System.Web.Management.EventLogWebEventProvider(具體)
    • System.Web.Management.IisTraceWebEventProvider(具體)
    • System.Web.Management.TraceWebEventProvider(具體)
    • System.Web.Management.WmiWebEventProvider(具體)
  • System.Web.Security.MembershipProvider-成員資格服務的自定義成員資格
    • System.Web.Security.ActiveDirectoryMembershipProvider(具體)
    • System.Web.Security.SqlMembershipProvider(具體)
  • System.Web.Security.RoleProvider-角色管理服務的自定義角色管理
    • System.Web.Security.AuthorizationStoreRoleProvider(具體)
    • System.Web.Security.SqlRoleProvider(具體)
    • System.Web.Security.WindowsTokenRoleProvider(具體)
  • System.Web.SessionState.SessionStateStoreProviderBase-會話狀態數據存儲
    • System.Web.SessionState.InProcSessionStateStore(具體)
    • System.Web.SessionState.OutOfProcSessionStateStore(具體)
    • System.Web.SessionState.SqlSessionStateStore(具體)
  • System.Web.SiteMapProvider-自定義SiteMap持久數據存儲
    • System.Web.StaticSiteMapProvider
      • System.Web.XmlSiteMapProvider(具體)
  • System.Web.UI.WebControls.WebParts.PersonalizationProvider-代表WebPartPersonalization實例加載和存儲個性化數據
    • System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider(具體)

例子:

我目前正在閱讀Roy Osherove 的《單元測試的藝術 》一書。 他提到了一種稱為“ 提取並重載”的技術(即,通過覆蓋負責返回依賴關系的虛擬方法,將依賴關系注入到類中)。

我想我遇到過該技術的各種實例,例如:

  • 自定義ADO.NET類型DataTable
    如果從DataTable派生,則可以覆蓋各種方法,例如GetRowType()CreateInstance()和其他方法。

  • 自定義Workflow Foundation Activity設計器(在.NET 3.5中)
    我不記得確切的類,但是我想如果您想創建自定義活動設計,則可以從現有的類中派生出新的類,並且模式大體相同。 您重寫了一個虛擬方法,該方法允許您將自定義依賴項返回到框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM