Ninject依賴注入(一)

Ninject學習筆記(一)

Ninject學習筆記(一)
理解依賴注入
DI概念
什么是DI?
DI是如何工作的?
什么是DI容器
使用Ninject
如何使用Ninject
Ninject對象生命周期
暫時范圍
單例范圍
線程范圍
請求范圍
自定義范圍
Ninject模塊
從xml配置依賴(Ninject XML擴展)
Ninject約定(Ninject Convention擴展)
選擇程序集
選擇組件
選擇服務類型
綁定配置

理解依賴注入

DI概念

依賴注入,或者控制反轉,降低代碼耦合度。Ninject是一個輕量級.NET DI框架。

什么是DI?

一個例子,木匠伐木,需要工具斧子。

  1. class Carpenter
  2. {
  3. Axe axe = new Axe();
  4. void Lumber()
  5. {
  6. axe.Cut();
  7. }
  8. }

代碼中,木匠依賴于斧子。此時需求變了,木匠買了木鋸,那么上面的代碼必須從新修改然后進行編譯。再比如木匠比較愛惜工具,決定兩種工具換著用,再比如,木匠決定提高生產率,購置了電鋸等等。作為程序員來說,如果每次需求變更就重新編碼,那么你會發現自己深陷沼澤地。

DI的出現就是為了解決這一問題的。它是一種編程方式,依賴關系不需要調用者來管理,統一由框架管理。“不要找我們,我們來找你”。

DI是如何工作的?

簡簡單單一句話——對接口編程,而不是對具體實現編程。用抽象元素來實現依賴,而不是具體類,如此一來我們可以很容易地替換具體的依賴類而不影響上層的調用組件。

  1. class ITool
  2. {
  3. void Cut();
  4. }
  5. class Carpenter
  6. {
  7. private ITool tool;
  8. void Carpenter(ITool tool)
  9. {
  10. tool = tool;
  11. }
  12. void Lumber()
  13. {
  14. tool.Cut();
  15. }
  16. }

什么是DI容器

DI容器是一個注入對象,用來向對象注入依賴性。一個應用中的依賴關系組成一個錯綜復雜的依賴圖。DI容器就是來管理依賴復雜性的。它決定抽象類選擇哪個實現類來實例化對象。Ninject有兩種定義依賴的方式:

  1. xml配置:<bind service="ITool to="Axe"/>
  2. 代碼定義:`Bind().To()

使用Ninject

如何使用Ninject

  1. 在VS編輯環境中->右鍵項目->選擇Nuget管理器->搜索Ninject->下載;
  2. 在項目中定義Kernel:var kernel = new StandardKernel()
  3. 通過kernel.Get方法獲取依賴的對象。

Ninject對象生命周期

暫時范圍

默認狀態,Ninject不管理它創建的對象,也就是每次請求都new一個新對象。

單例范圍

有兩種方式創建單例

  1. 使用單例模式
  1. class ConsoleLogger:ILogger
  2. {
  3. public static readonly ConsoleLogger Instance = new ConsoleLogger();
  4. private static ConsoleLogger()
  5. {
  6. // Hiding constructor
  7. }
  8. public void Log(string message)
  9. {
  10. Console.WriteLine("{0}: {1}", DateTime.Now, message);
  11. }
  12. }

然后在Bind方法后調用ToConstant方法指定靜態只讀對象ConsoleLogger.Instance為常量對象。
kernel.Bind<ILogger>().ToConstant(ConsoleLogger.Instance);

  1. 使用InSingletonScope方法——更簡單的方法
    kernel.Bind<ILogger>().To<ConsoleLogger>().InSingletonScope();

  2. 指定某個類為單例
    kernel.Bind<ConsoleLogger>.ToSelf().InThreadScope();

線程范圍

每一個線程只創建一個給定類型的對象。對象的生命周期和線程一樣長。
kernel.Bind<object>().ToSelf().InThreadScope();

請求范圍

用在Web應用程序中非常有用。在相同的請求范圍內得到一個單例的對象。需要添加Ninject.Web.Common引用。
kernel.Bind<SampleClass>().ToSelf().InRequestScope();

自定義范圍

自定義范圍讓我們定義我們自己的范圍,在這個范圍內保持一類型的唯一對象。只要提供的回調方法返回的對象引用是一樣的,Ninject在這個范圍內返回相同的實例。只要返回的對象引用變了,將創建一新的指定類型的對象。創建的對象實例將一直保存在緩存里,直到返回的范圍對象被垃圾回收器回收。一旦范圍對象被垃圾回收器回收,Ninject創建的所有的對象實例將被從緩存中釋放和處理。
調用InScope方法傳入Lamda表達式定義自定義返回:kernel.Bind<object>().ToSelf().InScope( ctx => User.Current );

自定義范圍是最靈活的,可以實現其他的范圍:

  1. 線程范圍:kernel.Bind<object>().ToSelf().InScope( ctx => Thread.CurrentThread);
  2. 請求范圍:kernel.Bind<object>().ToSelf().InScope( ctx => HttpContext.Current);

Ninject模塊

如果應用程序規模比較大,那么注冊的服務列表將會非常長,維護變得困難。一種好的方式是進行分組管理。Ninject提供了這個功能。每個組稱為一個Ninject模塊,只需要編寫一個類實現INinjectModule接口,需要實現三個方法和兩個屬性。好消息是,Ninject還提供了一個實現該接口的抽象類NinjectModule,無需每次都實現接口的所有方法。
將多個模塊加載到單個Ninject Kernel中的方法:
var kernel = new StandardKernel(new Module1(), new Module2(), ...)
也可以將應用程序中所有的模塊同時加載到Ninject Kernel中:
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());

從xml配置依賴(Ninject XML擴展)

需要Ninject XML擴展引用。注意記得發布xml文件時選擇“Copy if newer”。
XML配置文件格式如下:

  1. <module name="moduleName">
  2.   <bind service="Namespace.IService1, AssemblyName"
  3.     to="Namespace.ConcreteService1, AssemblyName" />
  4.   <bind service="Namespace.IService2, AssemblyName"
  5.     to="Namespace.ConcreteService2, AssemblyName"
  6.     Scope="singleton"/>
  7. </module>

加載XML文件到Kernel的方法:
kernel.Load("module1.xml","module2.xml","module3.xml");
可以使用相對輸出路徑的路徑,也可以使用絕對路徑,還可以使用通配符:
kernel.Load("Modules/*.xml);

Ninject約定(Ninject Convention擴展)

小的應用中,一個一個注冊服務類型并不困難,但是一個有上百個服務的應用程序呢?約定配置允許我們綁定一組服務,而不是一個個分別綁定。

注冊一個約定綁定需要三個步驟:選擇包含具體類的程序集、選擇程序集中的具體組件、選擇具體組件相關的服務類型。

選擇程序集

  1. FromThisAssembly():選擇包含當前代碼的程序集;
  2. From(params Assembly[] assemblies):選擇指定程序集;
  3. FromAssemblyContaining<SomeType>():選擇包含指定類的程序集;
  4. Join():選擇多個程序集。
  1. kernel.Bind(x => x
  2. .FromAssemblyContaining<CustomersService>()
  3. .SelectAllClasses()
  4. .Join()
  5. .FromAssemblyContaining<MessageProvider>()
  6. .SelectAllClasses()
  7. .BindAllInterfaces());

默認情況下只有公有類型可以在程序集中被邦迪。為包含非公有類型,需要在選擇程序集后顯式調用IncludingNonePublicTypes方法:

  1. kernel.Bind(x => x
  2. .FromAssemblyContaining<CustomersService>()
  3. .IncludingNonePublicTypes()
  4. .SelectAllClasses()
  5. .BindAllInterfaces());

選擇組件

選擇要注冊的組件。

  1. SelectAllClasses():選擇所有的非抽象類;
  2. Select(Func<Type, bool> filter):選擇需要的類。
    例子:選擇以“Customer"開頭的所有類:
  1. kernel.Bind(r => r
  2. .FromThisAssembly()
  3. .Select(t =>t.Name.StartsWith("Customer"))
  4. .BindBase());

例子:用條件對結果進行過濾:

  1. kernel.Bind(x => x
  2. .FromThisAssembly()
  3. .SelectAllClasses()
  4. .InNamespaces("Northwind.Controllers")
  5. .BindBase());

選擇服務類型

  • BindAllInterfaces(): 綁定所有的選擇的組件的接口到選擇的組件。
  • BindBase(): 綁定選擇的組件的基類型到當前的組件。
  • BindDefaultInterface(): 綁定指定類型的默認接口到類型。類型的默認接口跟類型同名。例如,ICustomerService是CutomerService的默認接口。
  • BindDefaultInterfaces(): 綁定指定類型的默認接口到類型。類型的默認接口是那些以類型的名字結尾的接口。例如,IRepository和ICustomerRepository都是SqlCustomerRepository的默認接口。
  • BindSingleInterface(): 要求指定類型只有一個接口。在這個情況下,這個接口綁定到這個類型。如果這個類型沒有或者有多個接口,則不添加綁定。
  • BindToSelf(): 綁定類型到自身。
  • BindSelection(ServiceSelector selector): 綁定選擇的接口到類型。
  • BindUsingRegex(string pattern): 綁定當前類型的符合正則表達式的接口到類型。

綁定配置

綁定創建后,可以像普通綁定的配置一樣進行配置:

  1. kernel.Bind(x => x
  2. .FromThisAssembly()
  3. .SelectAllClasses()
  4. .BindAllInterfaces()
  5. .Configure(b=>b.InSingletonScope()));

我們也可以使用ConfigureFor方法對某些類型分別進行配置。下面的例子,所有的repository類在構造函數中都注入"connectionString"參數,配置成單例生命周期。SqlCustomerRepository類重載成線程生命周期:

  1. kernel.Bind(x => x
  2. .FromThisAssembly()
  3. .SelectAllClasses()
  4. .InheritedFrom<IRepository>()
  5. .BindAllInterfaces()
  6. .Configure(b =>b.InSingletonScope ()
  7. .WithConstructorArgument("connectionString", ApplicationSettings.
  8. ConnectionString))
  9. .ConfigureFor<SqlCustomerRepository>(b =>b.InThreadScope()));


null


轉載于:https://www.cnblogs.com/qianzi067/p/6594463.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372609.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

我如何向團隊解釋依賴注入

最近&#xff0c;我們公司開始開發基于Java的新Web應用程序&#xff0c;經過一些評估過程&#xff0c;我們決定使用Spring。 但是許多團隊成員并不了解Spring和Dependency Injection的原理。 因此&#xff0c;我被要求給出一個速成班&#xff0c;介紹什么是Spring上的依賴注入和…

可以添加自定義的Select控件

1.控件dom <select name"WebSiteTarget" id"WebSiteTarget" class"w1" onchange"editable2(this);"><option value"-1">請選擇城市</option><option>福州</option><option>廈門</op…

innodb_io_capacity =innodb_lru_scan_depth*inoodb_buffer_pool_instances。與 checkpoint

innodb_lru_scan_depth:每個緩沖池刷臟頁的能力 innodb_io_capacity: iops inoodb_buffer_pool_instances8 :緩沖池的個數 .關系&#xff1a; innodb_io_capacity > innodb_lru_scan_depth * inoodb_buffer_pool_instances 轉載于:https://www.cnblogs.com/zengkefu/…

Java中的責任鏈模式

當應有幾個處理器來執行某項操作并為這些處理器定義特定順序時&#xff0c;就需要采用責任鏈設計模式。 在運行時處理器順序的可變性也很重要。模式的UML表示如下&#xff1a; 處理程序定義處理器對象的一般結構。 這里的“ HandleRequest”是抽象處理器方法。 處理程序還具有自…

php的excel源碼下載,PHPExcel-5 - 源碼下載|Windows編程|其他小程序|源代碼 - 源碼中國...

文件名大小更新時間PHPExcel02019-05-11PHPExcel\.gitattributes702019-01-02PHPExcel\.gitignore1082019-01-02PHPExcel\.travis.yml5122019-01-02PHPExcel\16329.xlsx510662019-05-11PHPExcel\19093.xlsx511932019-05-11PHPExcel\43877.xlsx530952019-05-11PHPExcel\62045.xl…

使用Visual Studio Code開發Asp.Net Core WebApi學習筆記(六)-- 依賴注入

本篇將介紹Asp.Net Core中一個非常重要的特性&#xff1a;依賴注入&#xff0c;并展示其簡單用法。 第一部分、概念介紹 Dependency Injection&#xff1a;又稱依賴注入&#xff0c;簡稱DI。在以前的開發方式中&#xff0c;層與層之間、類與類之間都是通過new一個對方的實例進行…

基于JAX-WS的webService開發實例

最近因為工作原因接觸到webService&#xff0c;所以記錄下開發中碰到的問題&#xff0c;方便自己以后復習&#xff0c;順便發揚一下開源精神。剛剛接觸webServie如果有什么錯誤歡迎大家指正。 本地環境&#xff1a;myEclipse10.6 tomcat7 JDK7 jaxws-ri-2.2.10 第一步&#xff…

完整的WebApplication JSF EJB JPA JAAS –第2部分

視圖–創建和JSF設置 本教程是第1部分的繼續。 讓我們創建一個新的Dynamic Web Project 。 如下圖所示創建它&#xff1a; 注意&#xff1a;在某些時候&#xff0c;Eclipse會詢問您是否要添加JSF功能&#xff08;自動完成&#xff09;&#xff0c;然后啟用它。 就像下面的屏幕…

lempel ziv matlab,基于Python的LempelZiv算法的熵估計

此函數允許估計時間序列的熵。它基于Lempel-Ziv壓縮算法。對于長度為n的時間序列&#xff0c;熵估計為&#xff1a;E(1/n和L_i)^-1 ln(n)式中&#xff0c;L逯i是從位置i開始的最短子串的長度&#xff0c;該子串之前沒有從位置1出現到i-1。當n接近無窮大時&#xff0c;估計的熵收…

Android使用繪圖Path總結

Path作為Android中一種相對復雜的繪圖方式&#xff0c;官方文檔中的有些解釋并不是很好理解&#xff0c;這里作一個相對全面一些的總結&#xff0c;供日后查看&#xff0c;也分享給大家&#xff0c;共同進步。 1.基本繪圖方法 addArc(RectF oval, float startAngle, float swee…

2017.3.23下午

下午通過對OSPF基本原理進一步的學習&#xff0c;對上午學習的內容進行了復習。 轉載于:https://www.cnblogs.com/bgd140206206/p/6606192.html

編寫Eclipse插件教程–第1部分

Eclipse是三個最受歡迎的Java開發IDE之一。 其成功的原因之一是其可擴展性。 對于任何知道該怎么做并且已經做到的人來說&#xff0c;編寫eclipse插件都可以非常輕松快捷。 不幸的是&#xff0c;第一次在Eclipse中進行操作可能會非常耗時且令人沮喪。 Eclipse框架非常龐大&…

簡單Window下 Android Studio的安裝

&#xff08;1&#xff09;首先安裝JDK 下載JDK 本人覺得官方網站下JDK比較慢&#xff0c;可以直接百度JDK&#xff0c;&#xff08;如果是64位 百度搜索記得64位&#xff09; 類似于這樣的下載 安裝可以看下教程&#xff0c;包括環境變量的配置 如何安裝JDK &#xff08;2&…

日期處理一之NSLalendar的使用

一、日期和時間模式 日期和時間格式由日期和時間模式字符串組成&#xff0c;在日期和時間模式字符串中未加引號的A到‘Z’和a到‘z’被解釋為模式字母&#xff0c;用來表示日期或時間。字符串元素&#xff0c;文本可以使用單引號&#xff08;‘’&#xff09;引起來使用。定義以…

java的使用Pair要導入什么包,第三方jar包的使用

被導入的外部類所在源文件通常要打包成jar包&#xff0c;java中的jar文件裝的是 .class 文件。它是一種壓縮格式和zip兼容&#xff0c;被稱為jar包。JDK提供的許多類&#xff0c;也是以jar包的形式提供的。在用的時候呢&#xff0c;你的文件里有很多個類&#xff0c;把這些類和…

十大最受歡迎的新Eclipse插件

Eclipse Marketplace仍然是發現有趣且相關的Eclipse插件的地方。 通過Eclipse Marketplace客戶端&#xff0c;每月成功安裝100,000多個基于Eclipse的產品。 我們提供了過去30天 以來所有時間最受歡迎的插件列表。 我認為看看過去12個月中最受歡迎的新插件會很有趣。 以下列出了…

在桌面顯示我電腦

打開Windows PowerShell&#xff08;一個像是命令提示符的東西[藍底白字]&#xff0c;但不是命令提示符&#xff09;&#xff0c;在Windows PowerShell內輸入cmd回車&#xff0c;當返回如下信息&#xff1a; Microsoft Windows [版本 6.2.9200](c) 2012 Microsoft Corporation。…

《Java技術》第二次作業計科1501趙健宇

&#xff08;一&#xff09;學習總結 1.使用Eclipse關聯jdk源代碼,查看String類的equals&#xff08;&#xff09;方法 equals&#xff08;&#xff09;方法截圖 “”比較的是地址。equals方法他同樣使用號進行內存地址的比較。但是equals方法重寫如果號比較不相等&#xff0c;…

注射php,UPDATE注射(mysqlphp)的兩個模式

一.測試環境&#xff1a;OS:Windowsxpsp2php:php4.3.10(mysql4.1.9apache1.3.33二.測試數據庫結構&#xff1a;-----start-----數據庫:test----------------------------------------------------------------表的結構userinfo--CREATETABLEuserinfo(groudidvarchar(12)NOTNULL…

JUnit的內置Hamcrest Core Matcher支持

在用JUnit和Hamcrest改進assertEquals的文章中&#xff0c;我簡要討論了Hamcrest “ 核心 ”匹配器與JUnit的現代版本“結合”在一起的情況。 在那篇文章中&#xff0c;我特別關注了JUnit的assertThat&#xff08;T&#xff0c;Matcher&#xff09;靜態方法與Hamcrest核心is()匹…