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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

autofac 作用域_.Net Core3.1下使用Autofac实现依赖注入

發(fā)布時間:2023/12/29 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 autofac 作用域_.Net Core3.1下使用Autofac实现依赖注入 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

Autofac是.NET領(lǐng)域最為流行的IOC框架之一,傳說是速度最快的一個。它和C#語言的結(jié)合非常緊密,在使用過程中對你的應用的侵入性幾乎為零,更容易與第三方的組件集成。主要優(yōu)點如下(此段描述為轉(zhuǎn)載):它是C#語言聯(lián)系很緊密,也就是說C#里的很多編程方式都可以為Autofac使用,例如可以用Lambda表達式注冊組件

較低的學習曲線,學習它非常的簡單,只要你理解了IoC和DI的概念以及在何時需要使用它們

XML配置支持

自動裝配

微軟的Orchad開源程序使用的就是Autofac,從該源碼可以看出它的方便和強大

準備工作

本文演示的項目時基于.Net Core3.1的,同時需要通過nuget下載安裝以下幾個dll文件:

基本用法

在前面的《基于Dapper的擴展方法來簡單封裝WebApi接口》一文中介紹過在.net core2.1中使用Autofac的方式,在ASP.NET Core 1.1 - 2.2 中, 你可以調(diào)用 WebHostBuilder 的 services.AddAutofac().。但這不適用于ASP.NET Core 3+ 或 .NET Core 3+ ,在 ASP.NET Core 3+ 需要你直接指定一個service provider factory而不是把它加入進service collection。基本用法的代碼如下:

首先修改Progam中的CreateHostBuilder方法,使用autofac的容器工廠替換系統(tǒng)默認的容器:public?static?IHostBuilder?CreateHostBuilder(string[]?args)?=>

Host.CreateDefaultBuilder(args)

.UseServiceProviderFactory(new?AutofacServiceProviderFactory())//使用autofac的容器工廠替換系統(tǒng)默認的容器

.ConfigureWebHostDefaults(webBuilder?=>

{

webBuilder.UseStartup();

});

然后在Startup中增加一個方法ConfigureContainerpublic?void?ConfigureContainer(ContainerBuilder?containerBuilder)

{

//指定服務的注冊

containerBuilder.RegisterType().As().InstancePerLifetimeScope().AsImplementedInterfaces();

containerBuilder.RegisterType().As().InstancePerLifetimeScope().AsImplementedInterfaces();

var?container?=?containerBuilder.Build();

IUserService?userService?=?container.Resolve();

IProductService?productService?=?container.Resolve();

userService.Show();

productService.Show();

}

調(diào)試運行,我們發(fā)現(xiàn)ConfigureContainer的方法并沒有被引用,但已經(jīng)可以進到這個方法里并實現(xiàn)的服務的注冊,這就是因為我們指定了UseServiceProviderFactory:

Autofac生命周期

簡單介紹,詳情請見參考資料://1、瞬時生命周期:注冊之后,每次獲取到的服務實例都不一樣(默認的注冊方式)

containerBuilder.RegisterType().As().InstancePerDependency();

//2、單例生命周期:整個容器中獲取的服務實例都是同一個

containerBuilder.RegisterType().As().SingleInstance();

//3、作用域生命周期:在相同作用域下獲取到的服務實例是相同的

containerBuilder.RegisterType().As().InstancePerLifetimeScope();

//4、作用域生命周期:可以指定到某一個作用域,然后在相同作用域下共享服務實例

containerBuilder.RegisterType().As().InstancePerMatchingLifetimeScope("My");

//5、http請求上下文的生命周期:在一次Http請求上下文中,共享一個組件實例。僅適用于asp.net?mvc開發(fā)。

containerBuilder.RegisterType().As().InstancePerRequest();

//6、擁有隱式關(guān)系類型的創(chuàng)建新的嵌套生命周期的作用域,在一個生命周期域中所擁有的實例創(chuàng)建的生命周期中,

//??????每一個依賴組件或調(diào)用Resolve()方法創(chuàng)建一個單一的共享的實例,并且子生命周期域共享父生命周期域中的實例

containerBuilder.RegisterType().InstancePerOwned();

實際項目中用法

上面的代碼只是簡單演示了下Autofac如何注冊服務實例的,在實際使用時我們不會這樣去寫代碼,每增加一個接口及其實現(xiàn),都需要手動注冊一下,這樣的耦合度太高。因此我們需要進行代碼優(yōu)化,下面將使用反射的方式來實現(xiàn)服務的注冊,改造上面的代碼:public?void?ConfigureContainer(ContainerBuilder?containerBuilder)

{

Assembly?service?=?Assembly.Load("AspNetCore.Ioc.Service");

Assembly?iservice?=?Assembly.Load("AspNetCore.Ioc.Interface");

containerBuilder.RegisterAssemblyTypes(service,?iservice)

.Where(t?=>?t.FullName.EndsWith("Service")?&&?!t.IsAbstract)?//類名以service結(jié)尾,且類型不能是抽象的

.InstancePerLifetimeScope()?//生命周期,,

.AsImplementedInterfaces()

.PropertiesAutowired();?//屬性注入

}

運行結(jié)果如下

一個接口多個實現(xiàn)的服務注冊

在實際應用中有這樣一種場景,比如IUserService接口被多個類繼承并實現(xiàn),那么此時應該如何注冊服務并實現(xiàn)調(diào)用呢?

其實上面Startup中的注冊方式就已經(jīng)滿足服務的注冊,只是需要在相應的Controller調(diào)用的地方修改即可,如:public?class?UserController?:?Controller

{

///?

///?IUserService服務實現(xiàn)的集合

///?

private?readonly?IEnumerable?_userServices?=?null;

public?UserController(IEnumerable?userServices)

{

_userServices?=?userServices;

}

public?IActionResult?Index()

{

foreach?(var?item?in?_userServices)

{

item.Show();

}

return?View();

}

}

調(diào)試運行的結(jié)果如下

值得說明的是,一個接口有多個實現(xiàn)的情況,在注冊服務的時候,可以選擇一些策略來實現(xiàn)只注冊其中某幾個實例,示例代碼如下://一個接口有多個實現(xiàn):注冊所有實現(xiàn)的服務實例

builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).As();

//一個接口有多個實現(xiàn):只注冊以A結(jié)尾的服務實例

builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).Where(c=>c.Name.EndsWith("A")).As();

//一個接口有多個實現(xiàn):注冊所有實現(xiàn)的服務實例,并排除UserServiceA服務實例

builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).Except().As();

隔離服務注冊的邏輯代碼

為了簡化Startup中的代碼,還可以自定義一個MyAutofacModule的方式,將服務注冊的代碼抽離出來,放到單獨的文件中。這時我們就需要新建一個MyAutofacModule類,并繼承Autofac.Module,同時重寫其中的Load方法,具體代碼如下:using?System.Linq;

using?System.Reflection;

using?Autofac;

using?Autofac.Configuration;

using?Microsoft.Extensions.Configuration;

namespace?AspNetCore.Ioc.Web.Utility

{

public?class?MyAutofacModule?:?Autofac.Module

{

protected?override?void?Load(ContainerBuilder?builder)

{

//反射程序集方式服務注冊

Assembly?service?=?Assembly.Load("AspNetCore.Ioc.Service");

Assembly?iservice?=?Assembly.Load("AspNetCore.Ioc.Interface");

builder.RegisterAssemblyTypes(service,?iservice)

.Where(t?=>?t.FullName.EndsWith("Service")?&&?!t.IsAbstract)?//類名以service結(jié)尾,且類型不能是抽象的

.InstancePerLifetimeScope()?//作用域生命周期

.AsImplementedInterfaces()

.PropertiesAutowired();?//屬性注入

}

}

}

重寫Load方法中的邏輯其實就是將原本 寫在Startup中的注冊代碼遷移到MyAutofacModule中,然后將Startup中的ConfigureContainer方法修改成如下:public?void?ConfigureContainer(ContainerBuilder?containerBuilder)

{

containerBuilder.RegisterModule();

}

具體運行結(jié)果這里就不展示,和前面的一樣。

配置文件的方式服務注冊

為了讓注冊服務的方式更靈活,我們還可以通過配置文件的方式來實現(xiàn),將所有的程序集信息放到配置文件中,這樣便于后期的程序擴展。那么首先來看下配置文件應該如何寫:

需要注意的是要將autofac.json文件的屬性改成始終復制

autofac.json文件:{

"defaultAssembly":?"AspNetCore.Ioc.Interface",?//接口所在的程序集名稱

"components":?[

{

"type":?"AspNetCore.Ioc.Service.UserService,AspNetCore.Ioc.Service",?//接口的實現(xiàn)?全名稱

"services":?[

{

"type":?"AspNetCore.Ioc.Interface.IUserService"?//?接口的全名稱

}

],

"instanceScope":?"single-instance",?//單例生命周期

"injectProperties":?true?//是否支持屬性注入

},

{

"type":?"AspNetCore.Ioc.Service.ProductService,AspNetCore.Ioc.Service",?//接口的實現(xiàn)?全名稱

"services":?[

{

"type":?"AspNetCore.Ioc.Interface.IProductService"?//?接口的全名稱

}

],

"instanceScope":?"single-instance",?//單例生命周期

"injectProperties":?true?//是否支持屬性注入

}

]

}

修改MyAutofacModule中的調(diào)用方法:protected?override?void?Load(ContainerBuilder?builder)

{

//Autofac?基于配置文件的服務注冊

IConfigurationBuilder?configurationBuilder?=?new?ConfigurationBuilder();

configurationBuilder.AddJsonFile("Config/autofac.json");

IConfigurationRoot?root?=?configurationBuilder.Build();

//開始讀取配置文件中的內(nèi)容

ConfigurationModule?module?=?new?ConfigurationModule(root);

//根據(jù)配置文件的內(nèi)容注冊服務

builder.RegisterModule(module);

}

運行結(jié)果如下

總結(jié)

到這里基本就完成了.net core3.1下使用Autofac的基本用法,當然還有其他的一些用法,比如Autofac中實現(xiàn)AOP等,本文暫時就到這里了。參考資料:

總結(jié)

以上是生活随笔為你收集整理的autofac 作用域_.Net Core3.1下使用Autofac实现依赖注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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