依賴注入(Dependency Injection,DI)是控制反轉(zhuǎn)(Inversion of Control,IOC)思想的實(shí)現(xiàn)方式,依賴注入簡化模塊的組裝過程,降低模塊之間的耦合度.
DI的幾個(gè)概念:
服務(wù)(Service):和框架請求之后返回的一個(gè)對象,可以是一個(gè)數(shù)據(jù)庫鏈接,也可以是一個(gè)文件處理的方法,或者是數(shù)據(jù)處理的一個(gè)過程方法
注冊服務(wù):將上面向框架要的這個(gè)服務(wù)先注冊,才能向框架請求
服務(wù)容器:負(fù)責(zé)管理注冊的服務(wù)
查詢服務(wù):創(chuàng)建對象及關(guān)聯(lián)對象
對象生命周期有三種:
(1)Transient(瞬態(tài)):獲取服務(wù)對象每次獲取都是一個(gè)新的對象
(2)Scoped(范圍):在特定范圍內(nèi)再次獲取為同一個(gè)對象
(3)Singleton(單例):就這一個(gè)對象,每次獲取都是他
如果一個(gè)類實(shí)現(xiàn)了IDisposable接口,則離開作用域后容器會自動調(diào)用對象的Dispose方法,參考Using
生命周期的選擇:如果類無狀態(tài),建議選為Singleton,如果類中有狀態(tài)且有Scope控制就使用Scoped
.Net中使用DI
1.根據(jù)類型來獲取和注冊服務(wù):
可以分別指定服務(wù)類型和實(shí)現(xiàn)類型.這兩者可能相同,也可能不同.服務(wù)類型可以是類,也可以是接口,一般面向接口編程更靈活
2…Net控制反轉(zhuǎn)組件取名為DependencyInjection,但是包含ServiceLocator的功能
3.ServiceCollection用來構(gòu)造容器對象IServiceProvider,調(diào)用ServiceCollection的BuliderServiceProvider()創(chuàng)建ServiceProvider,可以用來獲取BuliderServiceProvider()之前ServiceCollection中的對象
安裝包需求:
Install-Package Microsoft.Extensions.DependencyInjection
using Microsoft.Extensions.DependencyInjection
GetService是根據(jù)注冊對象來返回的
GetRequiredService:沒有服務(wù)就拋出異常,因?yàn)閞equired是必須有服務(wù),當(dāng)有多個(gè)服務(wù)的時(shí)候獲取的是最后一個(gè)服務(wù)
GetServices:獲取注冊的所有的服務(wù),文章來源:http://www.zghlxwxcb.cn/news/detail-410803.html
public interface ITestService
{
public string Name{get;set;}
public void SayHi();
}
public class TestServiceImpl:ItestService
{
public string Name{get;set;}
public void SayHi()
{
Console.WriteLine($"Hi,I'm{Name}");
}
}
public class TestServiceImpl2:ItestService
{
public string Name{get;set;}
public void SayHi()
{
Console.WriteLine($"你好,我是{Name}");
}
}
static void Main(string[] args)
{
#region 直接注冊實(shí)現(xiàn)類,和接口沒有關(guān)系,將實(shí)現(xiàn)類注冊到服務(wù)容器中,然后通過實(shí)現(xiàn)類獲取服務(wù)
ServiceCollection services=new ServiceCollection();
services.AddTransient<TestServiceImpl>();
//下面是兩種申請服務(wù)的方法,一種是sp.GetServices/一種是sp.CreateScope()
using(ServiceProvider sp= services.BulidServiceProvider())
{
TestServiceImpl tsi=sp.GetService<TestServiceImpl>();
t.Name="cdc";
t.SayHi();
using(IServiceScope scope1=sp.CreateScope())
{
TestServiceImpl t=scope1.ServiceProvider.GetService<TestServiceImpl>();
}
}
#endregion
}
static void Main(string[] args)
{
ServiceCollection services=new ServiceCollection();
//注冊類型是接口,實(shí)現(xiàn)類型是方法
services.AddScoped<ITestService,TestServiceImpl>();
//這種寫法是為了傳參數(shù)
services.AddSingleton<ITestService,new TestServiceImpl()>
using(ServiceProvider sp=services.BulidServiceProvider())
{
ITestService ts1=sp.GetService<ITestService>();
//ITestService ts1=(ITestService)sp.GetService(typeof(ITestService));
ts1.Name="cdc";
ts1.SayHi();
}
}
DI會傳染的簡單范例文章來源地址http://www.zghlxwxcb.cn/news/detail-410803.html
namespace DIGOALL
{
class Progrom
{
static void Main(string[] args)
{
ServiceClolection services=new ServiceCollection();
services.AddScoped<Controller>();
services.AddScoped<ILog,LogImpl>();
services.AddScoped<IStorage,StorageImpl>();
services.AddScoped<IConfig,ConfigImpl>();
using(var sp= services.BulidServiceProvider())
{
var c=sp.GetRequiredService<Controller>();
c.Test();
}
Console.ReadKey();
}
}
class Controller
{
private readonly ILog log;
private readonly IStorage storage;
public Controller(ILog log,IStorage storage)
{
this.log=log;
this.storage=storage;
}
public void Test()
{
this.log.Log("開始上傳");
this.storage.Save("寫入的東西","1.txt");
this.log.Log("上傳完畢");
}
}
#region 日志類
interface ILog
{
public void Log(string msg);
}
class LogImpl:ILog
{
public void Log(string msg)
{
Console.WriteLine($"日志:{msg}");
}
}
#endregion
#region
interface IConfig
{
public string GetValue(string name);
}
class ConfigImpl:IConfig
{
public void GetValue(string name)
{
return "hello";
}
}
#endregion
#region 云存儲
interface IStorage
{
public void Save(string content,string name);
}
class StorageImpl:IStorage
{
**關(guān)鍵點(diǎn):獲取配置服務(wù),構(gòu)造函數(shù)中賦值給成員變量**
private readonly IConfig config;
public StorageImpl(IConfig config)
{
this.config=config;
}
public void Save(string content,string name)
{
string server=config.GetValue("server");
Console.WriteLine($"向服務(wù)器{server}的文件名為{name}上傳{content}");
}
}
#endregion
}
到了這里,關(guān)于.Net6.0系列-7 依賴注入(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!