日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.Net Core中依赖注入服务使用总结

發(fā)布時(shí)間:2023/12/4 asp.net 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Core中依赖注入服务使用总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、依賴注入

  引入依賴注入的目的是為了解耦和。說(shuō)白了就是面向接口編程,通過(guò)調(diào)用接口的方法,而不直接實(shí)例化對(duì)象去調(diào)用。這樣做的好處就是如果添加了另一個(gè)種實(shí)現(xiàn)類,不需要修改之前代碼,只需要修改注入的地方將實(shí)現(xiàn)類替換。上面的說(shuō)的通過(guò)接口調(diào)用方法,實(shí)際上還是需要去實(shí)例化接口的實(shí)現(xiàn)類,只不過(guò)不需要我們手動(dòng)new 構(gòu)造實(shí)現(xiàn)類,而是交給如微軟的DI、Autofac這些工具去構(gòu)建實(shí)現(xiàn)類。我們只需要告訴它們,某個(gè)類是某個(gè)接口的實(shí)現(xiàn)類,當(dāng)用到的時(shí)候,工具會(huì)自動(dòng)通過(guò)構(gòu)造函數(shù)實(shí)例化類。

二、.Net Core中自帶的DI

  本來(lái)想寫依賴注入源碼的講解的,看到網(wǎng)上有篇文章關(guān)于源碼講解的,很詳細(xì)、清楚,就不再寫了。地址:http://www.cnblogs.com/bill-shooting/p/5540665.html。我在這里就說(shuō)說(shuō)使用吧。

  依賴注入有三種生命周期,每種生命周期的注入方式大同小異,下面我以作用域生命周期舉例,其他兩種跟這個(gè)不同,我會(huì)特別說(shuō)明。

下面為用到的兩個(gè)服務(wù)。

public class UserService : IUserService
{
public string GetName()
{
return "UserName";
}
}

public interface IUserService
{
string GetName();
}
public class ConfigReader : IConfigReader
{
private string configFilePath;//需要傳一個(gè)路徑,去讀取路徑下文件的內(nèi)容
public ConfigReader(string configFileName)
{
this.configFilePath = configFileName;
}
public string Reader()
{
return File.ReadAllText(configFilePath);
}
}

public interface IConfigReader
{
string Reader();
}

 

1、最常用的注入方式,以接口形式暴露服務(wù)

services.AddScoped(typeof(IUserService), typeof(UserService));

services.AddScoped
<IUserService, UserService>();

兩種注入方式是一個(gè)意思,這種方式適合實(shí)現(xiàn)類為無(wú)參構(gòu)造函數(shù)或者有參構(gòu)造函數(shù)中參數(shù)已經(jīng)被注入過(guò)了。

 ? 2、自己注入自己,以實(shí)現(xiàn)形式暴露服務(wù)

services.AddScoped<UserService>();


services.AddScoped(typeof(UserService));

這種注入方式適合只有實(shí)現(xiàn)類,沒(méi)有借口類的注冊(cè)。

  3、需要傳參的構(gòu)造函數(shù)的類的注入

services.AddScoped<IConfigReader, ConfigReader>(x => { return new ConfigReader("c:/a.txt"); });
services.AddScoped
<IConfigReader>(x => { return new ConfigReader("c:/a.txt"); });

services.AddScoped(
typeof(IConfigReader), x => { return new ConfigReader("c:/a.txt"); });

前兩個(gè)匿名方法參數(shù)是IServiceProvider,返回值為一個(gè)實(shí)例,第三個(gè)返回值是Object。上面舉的例子沒(méi)有用到IServiceProvider ,下面再舉一個(gè)例子。修改上面的UserService類,將構(gòu)造方法需要一個(gè)IConfigReader參數(shù)。

public class UserService : IUserService
{
private IConfigReader configReader;

public UserService(IConfigReader configReader)
{
this.configReader = configReader;
}
public string GetName()
{
return "UserName" + configReader.Reader();
}
}

注冊(cè)的時(shí)候,如下:

services.AddScoped<IConfigReader, ConfigReader>(x => { return new ConfigReader("c:/a.txt"); });
//通過(guò)ServiceProvider獲取已經(jīng)注冊(cè)的IConfigReader
services.AddScoped
<IUserService, UserService>(x => { return new UserService(x.GetService<IConfigReader>()); });
//或者
services.AddScoped<IUserService, UserService>(x => { return new UserService(new ConfigReader("c:/a.txt")); });

?單例類型的生命周期多了兩種注入方式:

services.AddSingleton<IConfigReader>(new ConfigReader("c:/a.txt"));

services.AddSingleton(typeof(IConfigReader), new ConfigReader("C:/a.txt"));

自帶的依賴注入工具也可以批量注入

var assembly = Assembly.GetExecutingAssembly()
.DefinedTypes
.Where(a
=> a.Name.EndsWith("Service") && !a.Name.StartsWith("I"));

foreach (var item in assembly)
{
services.AddTransient(item.GetInterfaces().FirstOrDefault(), item);
}

?注意:當(dāng)一個(gè)服務(wù)有多個(gè)實(shí)現(xiàn)時(shí),調(diào)用的時(shí)候通過(guò) IEnumerable<IPayService> PayServices 獲取所有的實(shí)現(xiàn)服務(wù)。

services.AddTransient<IPayService, AliPayService>();
services.AddTransient
<IPayService, WeChatPayService>();

使用的時(shí)候:

三、Autofac

  1、以接口形式暴露服務(wù)

public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

var builder = new ContainerBuilder();
builder.Populate(services);

builder.RegisterType
<UserService>().As<IUserService>().InstancePerLifetimeScope();

var container = builder.Build();
return new AutofacServiceProvider(container);
}

  2、通過(guò)實(shí)現(xiàn)類暴露服務(wù)

builder.RegisterType<UserService>();

  3、需要傳參的構(gòu)造函數(shù)的類的注入

builder.Register(c => new ConfigReader("c:/a.txt")).As<IConfigReader>();

  4、通過(guò)程序集注入

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(c
=> c.Name.EndsWith("Service"))
.AsImplementedInterfaces();

總結(jié):

不論是微軟的依賴注入組件還是Autofac 原理都是先將接口和對(duì)應(yīng)的實(shí)現(xiàn)類注入到容器中,當(dāng)要使用的時(shí)候,組件會(huì)自動(dòng)通過(guò)構(gòu)造函數(shù)創(chuàng)建實(shí)例。這里有個(gè)問(wèn)題如果有個(gè)實(shí)現(xiàn)類有多個(gè)構(gòu)造函數(shù),組件會(huì)找滿足參數(shù)最多的那個(gè)構(gòu)造函數(shù)。

原文地址:https://www.cnblogs.com/MicroHeart/p/10861366.html

.NET社區(qū)新聞,深度好文,歡迎訪問(wèn)公眾號(hào)文章匯總?http://www.csharpkit.com?


總結(jié)

以上是生活随笔為你收集整理的.Net Core中依赖注入服务使用总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。