net core WebApi——依賴注入Autofac


前言

周末加班,下午犯困,整理下之前鼓搗過的東西,看過我之前的webapi系列的讀者知道,我之前試過Aspect,但是升級到3.0之后沒往下去試了,當時還留了個坑,這不,現在果斷移除了換成這個了。

Autofac

這個第三方類庫呢,是Ioc的容器,可以簡化我們很大的工作量,比如說在之前我們需要寫個類去聲明接口與實現,而用了這個容器呢,就不需要了,當然還是需要些配置的。

首先,引入第三方類庫,不多說。

引入

然后開始配置吧,首先先來看Program,添加AutofacServiceProviderFactory

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseServiceProviderFactory(new AutofacServiceProviderFactory());

改完之后呢,我們果斷就來到了Startup,只要是配置,當然要看入口文件跟這個配置文件了。

3.x呢有個變化就是Autofac要通過ConfigureContainer這個傳入容器的方法來配置了,不需要自己再創建。

        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());
            });

            // 通過Autofac自動完成依賴注入
            container.RegisterTypes(allTypes.ToArray())
                .AsImplementedInterfaces()
                .PropertiesAutowired()
                .InstancePerDependency();

            // 注冊Controller
            container.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly)
                .Where(t => typeof(Controller).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.Ordinal))
                .PropertiesAutowired();
        }

通過RegisterTypes的注冊方法將對應工程,也就是April.Service下的類接口與實現自動綁定,當然你也可以通過注冊接口的方法一個個來,但是我懶,比如:

// 一個
builder.RegisterType<StudentService>().As<IStudentService>();
// 一對多
builder.RegisterType<StudentService>().As<IStudentService>().As<ITestService>();

這里注意,聲明綁定一般是一對一,當然也可以是一對多,如果多次注冊聲明一個類,會取最后一次注冊的聲明作為實際操作的類。

好了,配置完成之后,我們來試下效果吧(當然我是已經注釋掉之前的ServiceInjection這個聲明方法了)。

在我們訪問Values的時候,我們看下IStudentService是否是null。
測試

OK,這已經說明通過Autofac這個容器,已經完成了一個工程里面的接口與實現的依賴關系了。

添加一個Util來隨時調用

在接觸的朋友中,有人給我反饋個信息,我不想每次寫方法都要構造函數來傳接口方法給我,也就是說我不要你覺得,我要我覺得。

好啊,你覺得方法自己要啥拿啥,可以,來個Util吧。

    public class AutofacUtil
    {
        public static ILifetimeScope Container { get; set; }

        /// <summary>
        /// 獲取服務(Single)
        /// </summary>
        /// <typeparam name="T">接口類型</typeparam>
        /// <returns></returns>
        public static T GetService<T>() where T : class
        {
            return Container.Resolve<T>();
        }

        /// <summary>
        /// 獲取服務(請求生命周期內)
        /// </summary>
        /// <typeparam name="T">接口類型</typeparam>
        /// <returns></returns>
        public static T GetScopeService<T>() where T : class
        {
            return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T));
        }
    }

在用之前,我們需要針對Container來個聲明實例化,Startup中的Configure添加下面一句。

            AutofacUtil.Container = app.ApplicationServices.GetAutofacRoot();

修改Values中的一部分來通過實例化的方式來調用接口。

            IStudentService studentService = AutofacUtil.GetScopeService<IStudentService>();

            StudentEntity entity = new StudentEntity
            {
                //新增
                Name = "小明",
                Age = 18,
                Number = "007",
                Sex = 0,
                Address = "大洛陽"
            };

            studentService.Insert(entity);

讓我們來看下效果吧。
測試

兩種方法,看個人習慣吧,我是推薦通過注入的方式,通過構造函數的方式來獲取接口實現。

小結

簡單記錄平時鼓搗的點點滴滴,有時候真是覺得,還是要多看多鼓搗,就像這個容器,在之前我通過一行一行的接口+實現來做綁定聲明,現在呢,只需要改造下,就可以一鍵無腦實例化,第三方庫的使用與否,個人覺得還是能踩着巨人的肩膀哪怕靠着也可以,自己一步步爬固然可嘉,也要學會變通,這樣方能提高效率,路漫漫其修遠兮

代碼地址

注意切換到3.0的分支。
github
gitee

預告

April-Admin,總算是要有個前后端聯動的工程了,一個名副其實的基礎工程。

前端基於Ant Design Pro
后端當然是net core 3.1
預覽


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM