欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net?WebApi中實(shí)現(xiàn)自動(dòng)依賴注入的三種方法(最新推薦)

 更新時(shí)間:2024年03月16日 09:08:24   作者:無顏組  
依賴關(guān)系注入 (DI) ,是一種軟件設(shè)計(jì)模式,這是一種在類及其依賴項(xiàng)之間實(shí)現(xiàn)控制反轉(zhuǎn) (IoC)?的技術(shù), .NET 中的依賴關(guān)系注入是框架的內(nèi)置部分,與配置、日志記錄和選項(xiàng)模式一樣,這篇文章主要介紹了.Net?WebApi中實(shí)現(xiàn)自動(dòng)依賴注入的三種方法,需要的朋友可以參考下

前言

該文僅供學(xué)習(xí)參考,如有問題請(qǐng)指正。

依賴關(guān)系注入 (DI) ,是一種軟件設(shè)計(jì)模式,這是一種在類及其依賴項(xiàng)之間實(shí)現(xiàn)控制反轉(zhuǎn) (IoC) 的技術(shù)。 .NET 中的依賴關(guān)系注入是框架的內(nèi)置部分,與配置、日志記錄和選項(xiàng)模式一樣。

生命周期

依賴注入有以下三種生命周期

  • 瞬時(shí) (Transient): 每次從服務(wù)容器進(jìn)行請(qǐng)求時(shí)創(chuàng)建的,請(qǐng)求結(jié)束后銷毀, 這種生存期適合輕量級(jí)、 無狀態(tài)的服務(wù)。
  • 作用域(Scoped):在指定的范圍內(nèi),第一次請(qǐng)求時(shí)會(huì)創(chuàng)建一個(gè)實(shí)例,重復(fù)請(qǐng)求時(shí),會(huì)返回同一個(gè)實(shí)例,在處理請(qǐng)求的應(yīng)用中,請(qǐng)求結(jié)束時(shí)會(huì)釋放有作用域的服務(wù)。使用 Entity Framework Core 時(shí),默認(rèn)情況下 AddDbContext 擴(kuò)展方法使用范圍內(nèi)生存期來注冊(cè) DbContext 類型。
  • 單例(Singleton):?jiǎn)卫芷谑亲铋L(zhǎng)的生命周期,整個(gè)應(yīng)用程序只會(huì)創(chuàng)建一個(gè)服務(wù)實(shí)例。這種生命周期適用于那些需要在整個(gè)應(yīng)用程序中共享狀態(tài)的服務(wù),例如配置(Configuration)類、緩存(Cache)類等。

用反射實(shí)現(xiàn)自動(dòng)依賴注入

定義三種生命周期的接口類

    /// <summary>
    /// 注入標(biāo)記,Scoped作用域,每次請(qǐng)求時(shí)創(chuàng)建一次
    /// </summary>
    public interface IScopedDependency
    {
    }
    /// <summary>
    /// 注入標(biāo)記,生命周期Singleton,服務(wù)第一次請(qǐng)求時(shí)創(chuàng)建,后續(xù)請(qǐng)求都使用相同的實(shí)例
    /// </summary>
    public interface ISingletonDependency
    {
    }
    /// <summary>
    /// 注入標(biāo)記,生命周期Transient,每次請(qǐng)求時(shí)被創(chuàng)建,適合輕量級(jí)服務(wù)
    /// </summary>
    public interface ITransientDependency
    {
    }
}

通過GetReferencedAssemblies實(shí)現(xiàn)

GetReferencedAssemblies該方法只能獲取當(dāng)前程序集所引用的外部程序集,不能獲取模式分離/間接引用的程序集
http://www.dbjr.com.cn/program/317858ubf.htm參考地址

/// <summary>
/// 動(dòng)態(tài)注冊(cè)所有服務(wù)
/// 約定:Interfaces(注入接口), IScopedDependency(生命周期),可以有泛型接口,其它不能再繼承。
/// 注意只能注入直接引用的,間接引用的不行
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddDynamicinjectionService(this IServiceCollection services)
{
	//當(dāng)前程序集
	var entryAssembly = Assembly.GetEntryAssembly();
	//獲取當(dāng)前程序集所引用的外部程序集,不能獲取模式分離/間接引用的程序集
	var types = entryAssembly!.GetReferencedAssemblies()
		.Select(Assembly.Load)//裝載
		.Concat(new List<Assembly>() { entryAssembly })//與本程序集合并
		.SelectMany(x => x.GetTypes())//獲取所有類
		.Where(x => !x.IsAbstract && x.IsClass)//排除抽象類
		.Distinct();
	//獲取所有繼承服務(wù)標(biāo)記的生命周期實(shí)現(xiàn)類
	var busTypes = types.Where(x => x.GetInterfaces().Any(t =>
					   t == typeof(ITransientDependency)
					|| t == typeof(IScopedDependency)
					|| t == typeof(ISingletonDependency));
	foreach (var busType in busTypes)
	{
		//過濾泛型接口
		var busInterface = busType.GetInterfaces()
			.Where(t => t != typeof(ITransientDependency)
						   && t != typeof(IScopedDependency)
						   && t != typeof(ISingletonDependency)
						   && !t.IsGenericType)
			.FirstOrDefault();
		if (busInterface == null) continue;
		if (typeof(ITransientDependency).IsAssignableFrom(busType))
			services.AddTransient(busInterface, busType);
		if (typeof(IScopedDependency).IsAssignableFrom(busType))
			services.AddScoped(busInterface, busType);
		if (typeof(ISingletonDependency).IsAssignableFrom(busType))
			services.AddSingleton(busInterface, busType);
	}
	return services;
}

在Program.cs 中添加該服務(wù)
builder.Services.AddDynamicinjectionService();

加載程序集路徑實(shí)現(xiàn)

只自動(dòng)注入該程序集路徑下的服務(wù),并且需要約定文件名稱

/// <summary>
/// 把系統(tǒng)所有Business添加到ServiceCollection
/// 加載程序集路徑動(dòng)態(tài)注入
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddBusService(this IServiceCollection services)
{
	string rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
	var busAssembly = Assembly.LoadFrom(Path.Combine(rootPath, "WenYan.Service.Business.dll"));
	var busTypes = busAssembly.GetTypes().Where(w => w.Name.EndsWith("Business")).ToList();
	foreach (var busType in busTypes)
	{
		var busInterface = busType.GetInterfaces().Where(w => w.Name.EndsWith("Business")).FirstOrDefault();
		if (busInterface == null) continue;
		if (typeof(ITransientDependency).IsAssignableFrom(busType))
			services.AddTransient(busInterface, busType);
		if (typeof(IScopedDependency).IsAssignableFrom(busType))
			services.AddScoped(busInterface, busType);
		if (typeof(ISingletonDependency).IsAssignableFrom(busType))
			services.AddSingleton(busInterface, busType);
	}
	return services;
}

通過依賴注入拓展庫(kù):Scrutor,使用非常簡(jiǎn)單,主要通過 FromAssemblyOf<> 掃描程序集和 AddClasses(o) 進(jìn)行篩選注冊(cè)

https://github.com/khellang/Scrutor 相關(guān)詳細(xì)文檔

services.Scan(scan => scan
    // 掃描特定類型所在的程序集,這里是 ITransientService 所在的程序集
    .FromAssemblyOf<ITransientService>()
        // .AddClasses 在上面獲取到的程序集中掃描所有公開、非抽象類型
        // 之后可以通過委托進(jìn)行類型篩選,例如下面只掃描實(shí)現(xiàn) ITransientService 的類型
        .AddClasses(classes => classes.AssignableTo<ITransientService>())
            // 將上面的類型作為它實(shí)現(xiàn)的所有接口進(jìn)行注冊(cè)
            // 如果類型實(shí)現(xiàn)了 N 個(gè)接口,那么就會(huì)有三個(gè)獨(dú)立的注冊(cè)
            .AsImplementedInterfaces()
            // 最后指定注冊(cè)的生存期,如瞬時(shí),作用域,還是單例
            .WithTransientLifetime()
        // 重復(fù)上面操作,比如這里掃描 IScopedService 所在的程序集
        .AddClasses(classes => classes.AssignableTo<IScopedService>())
            // 這里和上面不一樣的是,這里指定只實(shí)現(xiàn)特定的幾口,也就是只注冊(cè)一次
            .As<IScopedService>()
            // 指定注冊(cè)的生存期
            .WithScopedLifetime()
        // 也支持泛型注冊(cè),單個(gè)泛型參數(shù)
        .AddClasses(classes => classes.AssignableTo(typeof(IOpenGeneric<>)))
            .AsImplementedInterfaces()
        // 多個(gè)泛型參數(shù)
        .AddClasses(classes => classes.AssignableTo(typeof(IQueryHandler<,>)))
 

參考鏈接

https://www.cnblogs.com/SaoJian/p/17462782.html

https://www.cnblogs.com/qianxingmu/p/13363193.html

https://furion.net/docs/dependency-injection

https://juejin.cn/post/7211158239135383611

到此這篇關(guān)于.Net WebApi中實(shí)現(xiàn)自動(dòng)依賴注入的三種方法的文章就介紹到這了,更多相關(guān).Net WebApi中實(shí)現(xiàn)自動(dòng)依賴注入的三種方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Grid或者DataTable中數(shù)據(jù)導(dǎo)出為Excel原來這么簡(jiǎn)單

    Grid或者DataTable中數(shù)據(jù)導(dǎo)出為Excel原來這么簡(jiǎn)單

    以前一直認(rèn)為,將Grid 或者DataTable中的數(shù)據(jù)導(dǎo)出到Excel功能實(shí)現(xiàn)會(huì)非常復(fù)雜,可能會(huì)想用什么類庫(kù)什么的或者實(shí)在太難就用csv算了,沒想到真的很簡(jiǎn)單,需要了解的朋友可以參考下
    2012-12-12
  • .NET醫(yī)院公眾號(hào)系統(tǒng)線程CPU雙高問題分析

    .NET醫(yī)院公眾號(hào)系統(tǒng)線程CPU雙高問題分析

    這篇文章主要介紹了.NET醫(yī)院公眾號(hào)系統(tǒng) 線程CPU雙高分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Visual Studio 2017如何用正則修改部分內(nèi)容詳解

    Visual Studio 2017如何用正則修改部分內(nèi)容詳解

    這篇文章主要給大家介紹了關(guān)于Visual Studio 2017如何用正則修改部分內(nèi)容的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • 淺析MVP模式中V-P交互問題及案例分享

    淺析MVP模式中V-P交互問題及案例分享

    如果從層次關(guān)系來講,MVP屬于Presentation層的設(shè)計(jì)模式。對(duì)于一個(gè)UI模塊來說,它的所有功能被分割為三個(gè)部分,分別通過Model、View和Presenter來承載。Model、View和Presenter相互協(xié)作,完成對(duì)最初數(shù)據(jù)的呈現(xiàn)和對(duì)用戶操作的響應(yīng),它們具有各自的職責(zé)劃分。
    2014-05-05
  • .Net Core中使用Grpc的方法

    .Net Core中使用Grpc的方法

    這篇文章主要介紹了.Net Core中使用Grpc的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 淺談ASP.NET Core的幾種托管方式

    淺談ASP.NET Core的幾種托管方式

    這篇文章主要介紹了淺談ASP.NET Core的幾種托管方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • asp.net顯示頁(yè)面執(zhí)行時(shí)間

    asp.net顯示頁(yè)面執(zhí)行時(shí)間

    Global.asax需要添加的代碼。利用我們了解當(dāng)前頁(yè)面的運(yùn)行效率。
    2009-03-03
  • ASP.NET加密解密算法分享

    ASP.NET加密解密算法分享

    這篇文章主要分享的是ASP.NET實(shí)現(xiàn)的加密解密算法,非常的簡(jiǎn)單使用,有需要的小伙伴快來參考下吧。
    2015-03-03
  • 最新評(píng)論