.NetCore內置IOC容器ServiceCollection
一、IOC介紹
IOC:全名(Inversion of Control
)-控制反轉
IOC意味著我們將對象的創建控制權交給了外部容器,我們不管它是如何創建的,我們只需要知道,當我們想要某個實例時,我們可以直接從這個外部容器中去拿,而再也不需要我們去new了,充分體現了DIP(依賴倒置原則),也體現了我們經常掛在嘴邊的面向接口編程。
DI:全名(Dependency Injection
)-依賴注入
DI意味著將類型之間的依賴關系注入到DI容器中
在之前的.Net Framework
中并沒有集成IOC
,雖然Microsoft自己有一套"Unity",想要使用IOC+DI時,還需要我們自己去安裝包,進行三部曲等等各種操作
比較流行的IOC容器技術:Autofac、Unity、NInject。。。
二、.NetCore內置IOC容器ServiceCollection
1、打開NuGet包管理器,安裝?Microsoft.Extensions.DependencyInjection
?包
2、實現代碼如下:
public?interface?ISqlHelper
{void?GetAll();
}
public?class?SqlServerHelper?:?ISqlHelper
{public?void?GetAll(){Console.WriteLine("this?is?"+typeof(SqlServerHelper));}
}
static?void?Main(string[]?args)
{ServiceCollection?services?=?new?ServiceCollection();services.AddTransient<ISqlHelper,?SqlServerHelper>();var?provider=services.BuildServiceProvider();var?sqlHelper=provider.GetService<ISqlHelper>();sqlHelper.GetAll();Console.ReadKey();
}
運行結果輸出:this is SqlServerHelper
當我們在執行業務邏輯時想要寫入一些日志(Log
),必然會當然依賴這個類,那么會形成了SqlHelper
類與Log
類之前的依賴關系,我們可以將之前的依賴關系轉移到DI
容器中,也就是依賴注入(DI
),然后在DI
容器獲取服務(對象)
示例代碼如下:
public?interface?ISqlHelper?
{void?GetAll();
}
public?class?SqlServerHelper?:?ISqlHelper?
{private?readonly?ILog?_ilog;public?SqlServerHelper(ILog?ilog)?{_ilog?=?ilog;}public?void?GetAll()?{_ilog.LogInfo($"我在{typeof(SqlServerHelper).Name}中,我是ilog");Console.WriteLine("this?is?"?+?typeof(SqlServerHelper).Name);}
}
public?interface?ILog?
{void?LogInfo(string?msg);
}
public?class?Log?:?ILog?
{public?void?LogInfo(string?msg)?{Console.WriteLine(msg);}
}
private?static?void?Main(string[]?args)?
{services.AddTransient<ILog,?Log>();//瞬時注入services.AddTransient<ISqlHelper,?SqlServerHelper>();//瞬時,每次的實例都是一個新的對象var?provider?=?services.BuildServiceProvider();//構建服務提供商var?sqlHelper?=?provider.GetService<ISqlHelper>();//獲取我們需要的服務實例sqlHelper.GetAll();Console.ReadKey();
}
如果如下:
我在SqlServerHelper中,我是ilog
this?is?SqlServerHelper
三、組件的生命周期
1、Transient
:瞬時,每次的實例都是一個新的對象
2、Singleton
:單例,全局唯一實例
3、Scoped
:作用域,在一個作用域中唯一實例,比如在Asp.Net Core
應用程序中一次請求相當于一個Scoped
Transient:瞬時,每次的實例都是一個新的對象
ServiceCollection?services?=?new?ServiceCollection();
services.AddTransient<ILog,?Log>();
services.AddTransient<ISqlHelper,?SqlServerHelper>();
var?provider?=?services.BuildServiceProvider();
var?sqlHelper?=?provider.GetService<ISqlHelper>();//首次獲取要使用的服務
sqlHelper?=?provider.GetService<ISqlHelper>();//獲取新的服務
sqlHelper.GetAll();

結果如下:

Singleton:單例,全局唯一實例
ServiceCollection?services?=?new?ServiceCollection();
services.AddSingleton<ILog,?Log>();
services.AddSingleton<ISqlHelper,?SqlServerHelper>();
var?provider?=?services.BuildServiceProvider();
var?sqlHelper?=?provider.GetService<ISqlHelper>();
sqlHelper?=?provider.GetService<ISqlHelper>();
sqlHelper.GetAll();
Console.ReadKey();

Scoped:作用域,在一個作用域中唯一實例
一個作用域
ServiceCollection?services?=?new?ServiceCollection();
services.AddScoped<ILog,?Log>();
services.AddScoped<ISqlHelper,?SqlServerHelper>();
var?provider?=?services.BuildServiceProvider();
var?scope1?=?provider.CreateScope();//在一個作用域下創建第一個子作用域???????
var?sqlHelper?=?scope1.ServiceProvider.GetService<ISqlHelper>();

新的作用域
ServiceCollection?services?=?new?ServiceCollection();
services.AddScoped<ILog,?Log>();
services.AddScoped<ISqlHelper,?SqlServerHelper>();
var?provider?=?services.BuildServiceProvider();
var?scope1?=?provider.CreateScope();
//在一個作用域下創建第一個子作用域???????
var?sqlHelper?=?scope1.ServiceProvider.GetService<ISqlHelper>();
var?scope2?=?provider.CreateScope();
//在一個作用域下創建第二個子作用域
sqlHelper?=?scope2.ServiceProvider.GetService<ISqlHelper>();

注意:由于是控制臺項目,只能用子作用域來體現作用域的特點,在web項目中,一次請求就相當于一個作用域
推薦閱讀
??生成條形碼二維碼DataMatrix條碼.EAN碼.39碼.交叉25碼.UPC碼.128碼.93碼.ISBN碼.Codabar等
??C#生成二維碼的兩種快捷方式
??ShellProgressBar控制臺中漂亮的顯示進度條
??C#10特性試用|全局和隱式usings
資料參考
??ServiceCollection 類 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn[1]
??ASP.NET Core 中的 ServiceProvider - hippieZhou - 博客園[2]
歡迎關注我的公眾號“Net分享”,技術文章第一時間推送 , 分享一些你可能注意不到的細節。

引用鏈接
[1]
?ServiceCollection 類 (Microsoft.Extensions.DependencyInjection) | Microsoft Learn:?https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection?view=dotnet-plat-ext-6.0
[2]:?https://blog.csdn.net/m1m2m3mmm/article/details/123231352