周末加班,下午犯困,整理下之前鼓搗過(guò)的東西,看過(guò)我之前的webapi系列的讀者知道,我之前試過(guò)Aspect,但是升級(jí)到3.0之后沒(méi)往下去試了,當(dāng)時(shí)還留了個(gè)坑,這不,現(xiàn)在果斷移除了換成這個(gè)了。 Autofac這個(gè)第三方類庫(kù)呢,是Ioc的容器,可以簡(jiǎn)化我們很大的工作量,比如說(shuō)在之前我們需要寫(xiě)個(gè)類去聲明接口與實(shí)現(xiàn),而用了這個(gè)容器呢,就不需要了,當(dāng)然還是需要些配置的。 首先,引入第三方類庫(kù),不多說(shuō)。 然后開(kāi)始配置吧,首先先來(lái)看Program,添加AutofacServiceProviderFactory。 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .UseServiceProviderFactory(new AutofacServiceProviderFactory()); 改完之后呢,我們果斷就來(lái)到了Startup,只要是配置,當(dāng)然要看入口文件跟這個(gè)配置文件了。 3.x呢有個(gè)變化就是Autofac要通過(guò)ConfigureContainer這個(gè)傳入容器的方法來(lái)配置了,不需要自己再創(chuàng)建。 private static readonly List<string> _Assemblies = new List<string>() { "April.Service" }; public void ConfigureContainer(ContainerBuilder container) { var assemblys = _Assemblies.Select(x => Assembly.Load(x)).ToList(); List<Type> allTypes = new List<Type>(); assemblys.ForEach(aAssembly => { allTypes.AddRange(aAssembly.GetTypes()); }); // 通過(guò)Autofac自動(dòng)完成依賴注入 container.RegisterTypes(allTypes.ToArray()) .AsImplementedInterfaces() .PropertiesAutowired() .InstancePerDependency(); // 注冊(cè)Controller container.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly) .Where(t => typeof(Controller).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.Ordinal)) .PropertiesAutowired(); } 通過(guò)RegisterTypes的注冊(cè)方法將對(duì)應(yīng)工程,也就是April.Service下的類接口與實(shí)現(xiàn)自動(dòng)綁定,當(dāng)然你也可以通過(guò)注冊(cè)接口的方法一個(gè)個(gè)來(lái),但是我懶,比如: // 一個(gè) builder.RegisterType<StudentService>().As<IStudentService>(); // 一對(duì)多 builder.RegisterType<StudentService>().As<IStudentService>().As<ITestService>();
好了,配置完成之后,我們來(lái)試下效果吧(當(dāng)然我是已經(jīng)注釋掉之前的ServiceInjection這個(gè)聲明方法了)。 在我們?cè)L問(wèn)Values的時(shí)候,我們看下IStudentService是否是null。 OK,這已經(jīng)說(shuō)明通過(guò)Autofac這個(gè)容器,已經(jīng)完成了一個(gè)工程里面的接口與實(shí)現(xiàn)的依賴關(guān)系了。 添加一個(gè)Util來(lái)隨時(shí)調(diào)用在接觸的朋友中,有人給我反饋個(gè)信息,我不想每次寫(xiě)方法都要構(gòu)造函數(shù)來(lái)傳接口方法給我,也就是說(shuō)我不要你覺(jué)得,我要我覺(jué)得。 好啊,你覺(jué)得方法自己要啥拿啥,可以,來(lái)個(gè)Util吧。 public class AutofacUtil { public static ILifetimeScope Container { get; set; } /// <summary> /// 獲取服務(wù)(Single) /// </summary> /// <typeparam name="T">接口類型</typeparam> /// <returns></returns> public static T GetService<T>() where T : class { return Container.Resolve<T>(); } /// <summary> /// 獲取服務(wù)(請(qǐng)求生命周期內(nèi)) /// </summary> /// <typeparam name="T">接口類型</typeparam> /// <returns></returns> public static T GetScopeService<T>() where T : class { return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T)); } } 在用之前,我們需要針對(duì)Container來(lái)個(gè)聲明實(shí)例化,Startup中的Configure添加下面一句。 AutofacUtil.Container = app.ApplicationServices.GetAutofacRoot(); 修改Values中的一部分來(lái)通過(guò)實(shí)例化的方式來(lái)調(diào)用接口。 IStudentService studentService = AutofacUtil.GetScopeService<IStudentService>(); StudentEntity entity = new StudentEntity { //新增 Name = "小明", Age = 18, Number = "007", Sex = 0, Address = "大洛陽(yáng)" }; studentService.Insert(entity); 讓我們來(lái)看下效果吧。 兩種方法,看個(gè)人習(xí)慣吧,我是推薦通過(guò)注入的方式,通過(guò)構(gòu)造函數(shù)的方式來(lái)獲取接口實(shí)現(xiàn)。 小結(jié)簡(jiǎn)單記錄平時(shí)鼓搗的點(diǎn)點(diǎn)滴滴,有時(shí)候真是覺(jué)得,還是要多看多鼓搗,就像這個(gè)容器,在之前我通過(guò)一行一行的接口+實(shí)現(xiàn)來(lái)做綁定聲明,現(xiàn)在呢,只需要改造下,就可以一鍵無(wú)腦實(shí)例化,第三方庫(kù)的使用與否,個(gè)人覺(jué)得還是能踩著巨人的肩膀哪怕靠著也可以,自己一步步爬固然可嘉,也要學(xué)會(huì)變通,這樣方能提高效率,路漫漫其修遠(yuǎn)兮。 代碼地址預(yù)告April-Admin,總算是要有個(gè)前后端聯(lián)動(dòng)的工程了,一個(gè)名副其實(shí)的基礎(chǔ)工程。 前端基于Ant Design Pro |
|
來(lái)自: 新進(jìn)小設(shè)計(jì) > 《待分類》