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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

autofac 作用域_C#编程之.Net Core 学习之路-AutoFac的使用

發布時間:2023/12/29 C# 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 autofac 作用域_C#编程之.Net Core 学习之路-AutoFac的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要向大家介紹了C#編程之.Net Core 學習之路-AutoFac的使用,通過具體的內容向大家展示,希望對大家學習C#編程有所幫助。

本文不介紹IoC和DI的概念,如果你對Ioc之前沒有了解的話,建議先去搜索一下相關的資料

這篇文章將簡單介紹一下AutoFac的基本使用以及在asp .net core中的應用

Autofac介紹

組件的三種注冊方式反射

現成的實例(new)

lambda表達式 (一個執行實例化對象的匿名方法)

下面是一些簡短的示例,我盡可能多的列出來一些常用的注冊方式,同時在注釋中解釋下“組件”、“服務”等一些名詞的含義//?創建注冊組件的buildervar?builder?=?new?ContainerBuilder();//根據類型注冊組件?ConsoleLogger?暴漏服務:ILoggerbuilder.RegisterType().As();//根據類型注冊組件?ConsoleLogger,暴漏其實現的所有服務(接口)builder.RegisterType().AsImplementedInterfaces();//?根據實例注冊組件?output??暴漏服務:TextWritervar?output?=?new?StringWriter();

builder.RegisterInstance(output).As();//表達式注冊組件,這里我們是在構造函數時傳參->"musection"???暴漏服務:IConfigReaderbuilder.Register(c?=new?ConfigReader("mysection")).As();//表達式注冊組件,解析時傳參var?service?=?scope.Resolve(???????????new?NamedParameter("section",?"mysection"));

//反射注冊組件,直接注冊了ConsoleLogger類(必須是具體的類),如果ConsoleLogger有多個構造函數,將會取參數最多的那個構造函數進行實例化builder.RegisterType();//反射注冊組件,手動指定構造函數,這里指定了調用?MyComponent(ILogger?log,IConfigReader?config)的構造函數進行注冊builder.RegisterType()

.UsingConstructor(typeof(ILogger),?typeof(IConfigReader));

//注冊MySingleton類中的靜態變量"Instance",ExternallyOwned()函數指定自己控制實例的生命周期,而不是由autofac自動釋放

builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();//一個組件暴漏兩個服務??builder.RegisterType().As().As();

//注冊當前程序集中以“Service”結尾的類builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t?=>?t.Name.EndsWith("Service")).AsImplementedInterfaces();//注冊"MyApp.Repository"程序集中所有的類builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();

//構建一個容器完成注冊var?rootcontainer?=?builder.Build();//可以通過下面這種方式手動獲取IConfigReader?的實現類//這種手動解析的方式需要?從生命周期作用域內獲取組件,以保證組件最終被釋放//不要直接從根容器rootcontainer中解析組件,很有可能會導致內存泄漏using(var?scope?=?rootcontainer.BeginLifetimeScope())

{??var?reader?=?scope.Resolve();

}

如果不止一個組件暴露了相同的服務, Autofac將使用最后注冊的組件作為服務的提供方。 想要覆蓋這種行為, 在注冊代碼后使用?PreserveExistingDefaults()?方法修改

生命周期using(var scope = rootcontainer.BeginLifetimeScope())

上面的這段代碼創建了一個生命周期作用域

生命周期作用域是可釋放的,在作用域內解析的組件一定要保證在using之內使用或者最后手動調用組件的Dispose()函數

避免被引用類的生命周期大于引用類的生命周期 :如service 引用 repository 如果repository的生命周期為單例,service的生命周期為perrequest。repository不會釋放,所以最終會造成相關的service始終無法釋放的情況(Captive Dependencies)

對于一個具體組件(類)的生命周期分為以下幾種(后面的函數是autofac對應的函數):每個依賴一個實例(Instance Per Dependency) (默認) ----InstancePerDependency()

單一實例(Single Instance)?單例?----SingleInstance()

每個生命周期作用域一個實例(Instance Per Lifetime Scope)----InstancePerLifetimeScope()

每個匹配的生命周期作用域一個實例(Instance Per Matching Lifetime Scope)----InstancePerMatchingLifetimeScope()

每個請求一個實例(Instance Per Request)?asp.net web請求----InstancePerRequest()

每次被擁有一個實例(Instance Per Owned) ----InstancePerOwned()

如果你以前在傳統的ASP.NET MVC項目中用過autofac,需要注意一些區別:.net Core中需要使用InstancePerLifetimeScope替代之前(傳統asp.net)的InstancePerRequest,保證每次HTTP請求只有唯一的依賴實例被創建。InstancePerRequest請求級別已經不存在了

.net Core中Web Api與Mvc的注冊方式一樣

.net Core中不再需要注冊控制器,控制器由.net core創建,不歸autofac管理(除了控制器的構造函數),這也解釋了為什么不再使用InstancePerRequest生命周期,但是可以通過AddControllersAsServices()函數改變,想要深入了解的可以查看:https://www.strathweb.com/2016/03/the-subtle-perils-of-controller-dependency-injection-in-asp-net-core-mvc/

AutoFac 在asp .net core中的使用

在.net core 中使用autofac還是比較簡單的,相比于傳統的asp.net web 項目,省去了很多步驟

引入nuget程序包:Autofac

Autofac.Extensions.DependencyInjection

startup 中代碼:public?static?IContainer?AutofacContainer;????//?This?method?gets?called?by?the?runtime.?Use?this?method?to?add?services?to?the?container.

public?IServiceProvider?ConfigureServices(IServiceCollection?services)

{????????//注冊服務進?IServiceCollection

services.AddMvc();

ContainerBuilder?builder?=?new?ContainerBuilder();????????//將services中的服務填充到Autofac中.

builder.Populate(services);????????//新模塊組件注冊

builder.RegisterModule();????????//創建容器.

AutofacContainer?=?builder.Build();????????//使用容器創建?AutofacServiceProvider

return?new?AutofacServiceProvider(AutofacContainer);

}上面代碼調用了builder的RegisterModule函數,這個函數需要傳入一個TModule的泛型,稱之為autofac的模塊

模塊的功能就是把所有相關的注冊配置都放在一個類中,使代碼更易于維護和配置,下面展示了DefaultModuleRegister中的代碼

DefaultModuleRegister:public?class?DefaultModuleRegister?:?Module{????protected?override?void?Load(ContainerBuilder?builder)????{????????//注冊當前程序集中以“Ser”結尾的類,暴漏類實現的所有接口,生命周期為PerLifetimeScope

builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t?=>?t.Name.EndsWith("Ser")).AsImplementedInterfaces().InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t?=>?t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();????????//注冊所有"MyApp.Repository"程序集中的類

//builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();

}????public?static?Assembly?GetAssembly(string?assemblyName)????{????????var?assembly?=?AssemblyLoadContext.Default.LoadFromAssemblyPath(AppContext.BaseDirectory?+?$"{assemblyName}.dll");????????return?assembly;

}

}

Configure函數中可以選擇性的加上程序停止時Autofac的釋放函數:public?void?Configure(IApplicationBuilder?app,?IHostingEnvironment?env,?IApplicationLifetime?appLifetime)

{????????if?(env.IsDevelopment())

{

app.UseDeveloperExceptionPage();

app.UseBrowserLink();

}????????else

{

app.UseExceptionHandler("/Home/Error");

}

app.UseStaticFiles();

app.UseMvc(routes?=>

{

routes.MapRoute(

name:?"default",????????????????template:?"{controller=Home}/{action=Index}/{id?}");

});????????//程序停止調用函數

appLifetime.ApplicationStopped.Register(()?=>?{?AutofacContainer.Dispose();?});

}

Controller中代碼:private?IUserSer?_user;????private?IUserSer?_user2;????public?HomeController(IUserSer?user,?IUserSer?user2)

{????????_user?=?user;????????_user2?=?user2;

}????public?IActionResult?Index()

{????????using?(var?scope?=?Startup.AutofacContainer.BeginLifetimeScope())

{????????????IConfiguration?config?=?scope.Resolve();????????????IHostingEnvironment?env?=?scope.Resolve();

}????????string?name?=?_user.GetName();????????string?name2?=?_user2.GetName();????????return?View();

}可以看到,因為我們將IServiceCollection中的服務填充到了autofac中了,所以現在可以在任何位置通過AutoFac解析出來.net core默認注入的服務(IConfiguration,IHostingEnvironment等)了

正常項目使用中,我們應該將AutofacContainer放在一個公共的類庫中以便各個工程均可調用

本文由職坐標整理并發布,希望對同學們有所幫助。了解更多詳情請關注職坐標編程語言C#.NET頻道!

總結

以上是生活随笔為你收集整理的autofac 作用域_C#编程之.Net Core 学习之路-AutoFac的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。