1、介紹html
依賴注入(也稱DI)是一種設計模式,其中一個類或對象將其依賴的類注入(由另外一個類或對象傳遞給它),而不是直接建立它們。依賴注入有利於促進鬆耦合,提升可測試性和維護性。此外,依賴注入容許更改實現,而無需更改利用這些實現的類或接口。
傳統的代碼,每一個對象負責管理與本身須要依賴的對象,致使若是須要切換依賴對象的實現類時,須要修改多處地方。同時,過分耦合也使得對象難以進行單元測試。若是後期需求變動,須要替換IUserInfoService的實現,好比從Mongodb中獲取數據,那麼就須要在全部new出UserInfoService的地方更改代碼換成UserInfoMongoService,git
// IUserInfoService _userInfoService = new UserInfoService(); IUserInfoService _userInfoService = new UserInfoMongoService();github
沒有IoC/DI的時候,常規的A類使用C類的示意圖,如圖所示:設計模式
當有了IoC/DI的容器後,A類再也不主動去建立C了,如圖所示:服務器
而是被動等待,等待IoC/DI的容器獲取一個C的實例,而後反向的注入到A類中,mvc
2、AutoFac的應用框架
AutoFac是一個開源的輕量級的DI容器,也是.net下最受歡迎的實現依賴注入的工具之一,經過AutoFac咱們能夠很方便的實現一些DI的操做。函數
參考網站:https://www.cnblogs.com/stulzq/p/8547277.html工具
依賴注入在ASP.Net中的生命週期單元測試
依賴注入生命週期用於指定什麼時候建立和從新建立依賴對象。 就ASP.Net代碼應用程序中依賴注入實例的生命週期而言。
1. InstancePerDependency:對每個依賴或每一次調用建立一個新的惟一的實例。這也是默認的建立實例的方式。。
2. SingleInstance:單例,全部服務請求都將會返回同一個實例。
3. InstancePerLifetimeScope:在一個嵌套語句塊中,只會返回一個實例,且每個不一樣的生命週期域,實例是惟一的,不共享的。
3、獲取用戶列表的簡單例子:
1.引用
Autofac: autofac框架核心類庫
2.接口:IUserInfoService
namespace Service { public interface IUserInfoService { List<UserInfo> GetUsers(); } }
3.實現類:UserInfoService
public class UserInfoService : IUserInfoService { //獲取用戶列表 public List<UserInfo> GetUsers() { return new List<UserInfo> { new UserInfo{ name="張三",age=12}, new UserInfo{ name="王五",age=12}, }; } }
4.Application_Start方法中進行注入
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //註冊組件 //AutofacConfig.Register();
//建立autofac管理註冊類的容器實例 var builder = new ContainerBuilder(); //註冊組件 builder.RegisterType<UserInfoService>().As<IUserInfoService>().SingleInstance(); //使用Autofac提供的RegisterControllers擴展方法來對程序集中全部的Controller一次性的完成註冊 builder.RegisterControllers(Assembly.GetExecutingAssembly()); //生成具體的實例 var container = builder.Build(); //下面就是使用MVC的擴展 更改了MVC中的注入方式. DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }
5.控制器
namespace AutoFacMvcDemo.Controllers { public class UserInfoController : Controller { private readonly IUserInfoService userinfoService; //經過構造器注入依賴 public UserInfoController(IUserInfoService _userinfoService) { userinfoService = _userinfoService; } public ActionResult Index() { //不使用autofac時,service層和mvc ui層強耦合 //UserInfoService userInfoService = new UserInfoService(); //List<UserInfo> users= userInfoService.GetUsers(); List<UserInfo> users= userinfoService.GetUsers(); ViewBag.users = users; return View(); } } }
4、常見框架 https://github.com/quozd/awesome-dotnet/blob/master/README.md#ioc
Castle Windsor:Castle Windsor是最佳的、成熟的控制反轉容器,可用於.NET和Silverlight
Unity:輕量級可擴展依賴項注入容器,支持構造函數、屬性和方法調用注入
autofac:一個上癮的.NET IOC容器
DRYIOC:簡單、快速的全功能IOC容器。
Ninject:.NET依賴注入器的忍者
StructureMap:用於.NET的原始IOC/DI容器
Spring.net:Spring.net是一個開源應用程序框架,使構建企業.NET應用程序更加容易。
一個快速的IOC容器,針對ASP.NET核心和其餘.NET服務器端應用程序的使用進行了大量優化。
LightInject:超輕IOC容器
Simple Injector:簡單注入器是一個易於使用的.NET 4+依賴項注入(DI)庫,支持Silverlight 4+、Windows Phone 八、Windows 8,包括通用應用程序和Mono。
Microsoft.Extensions.DependencyInjection:ASP.NET核心應用程序的默認IOC容器。
Scrutor:程序集掃描Microsoft.Extensions.DependencyInjection的擴展。
vs mef:Visual Studio使用的託管擴展性框架(mef)實現。
Tinyioc:是一個易於使用、無需麻煩的控制容器,適用於小型項目、庫和初學者。
stashbox:是一個輕量級的、可移植的依賴注入框架,用於基於.NET的解決方案。
5、總結:
1. 依賴注入把對象的創造交給外部去管理,很好的解決了代碼緊耦合(tight couple)的問題,是一種讓代碼實現鬆耦合(loose couple)的機制。
2.鬆耦合讓代碼更具靈活性,能更好地應對需求變更。
3.依賴注入和控制反轉是對同一件事情的不一樣描述,依賴注入是從應用程序的角度在描述,應用程序依賴容器建立並注入它所須要的外部資源;控制反轉是從容器的角度在描述,由容器反向的嚮應用程序注入應用程序所須要的外部資源。
參考網站:
https://www.cnblogs.com/yangecnu/p/Introduce-Dependency-Injection.html
https://blog.csdn.net/ad996454914/article/details/80901105
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
---------------------------------------------------------------------------------------------------------
依賴注入和控制反轉 參考公衆號:https://mp.weixin.qq.com/s/EokhamT9p_dk_w22QojxdQ
誰依賴於誰:固然是某個對象依賴於IoC/DI的容器
爲何須要依賴:對象須要IoC/DI的容器來提供對象須要的外部資源
誰注入於誰:很明顯是IoC/DI的容器 注入 某個對象
到底注入什麼:就是注入某個對象所須要的外部資源
誰控制誰:固然是IoC/DI的容器來控制對象了
控制什麼:主要是控制對象實例的建立
爲什麼叫反轉:反轉是相對於正向而言的,那麼什麼算是正向的呢?考慮一下常規狀況下的應用程序,若是要在A裏面使用C,你會怎麼作呢?固然是直接去建立C的對象,也就是說,是在A類中主動去獲取所須要的外部資源C,這種狀況被稱爲正向的。那麼什麼是反向呢?就是A類再也不主動去獲取C,而是被動等待,等待IoC/DI的容器獲取一個C的實例,而後反向的注入到A類中。