ASP.NET Core依賴注入&AutoFac


1. 前言

關於IOC模式和DI技術,網上已經有很多相關的探討,再次就不過多贅述了,只是簡單介紹一下它們的概念

  • 控制反轉(IoC/Inverse Of Control):   調用者將創建實例的控制權交給IOC容器,由容器創建,所以稱為控制反轉。
  • 依賴注入(DI/Dependence injection) :   容器創建好實例后再注入給調用者的過程稱為依賴注入。依賴注入技術讓我們的應用程序實現了松散耦合

.NetFramewok和.Net Core的區別之一就是.net core所有的實例都是通過依賴注入來創建的。下面介紹一下ASP.NET CORE中如何使用依賴注入

2.ASP.NET Core 中自帶的DI方式

ASP.NET Core本身已經集成了一個輕量級的IOC容器,開發者只需要定義好接口后,在Startup.cs的ConfigureServices方法里使用對應生命周期的綁定方法即可

例:

            //注冊數據庫基礎操作
            services.AddScoped(typeof(IBLLConstruct<>), typeof(BLLConstruct<>));
            //注冊緩存操作
            services.AddTransient(typeof(ICacheContext), typeof(CacheContext));
            services.AddScoped(typeof(IAuth), typeof(LocalAuth));
            services.AddSingleton(typeof(IHttpContextAccessor), 
            typeof(HttpContextAccessor));
AddTransient:服務在每次請求時被創建
AddScoped:服務在每次請求時被創建,生命周期橫貫整次請求
AddSingleton:顧名思義Singleton(單例),服務在第一次請求時被創建(或者當我們在ConfigureServices中指定創建某一實例並運行方法),其后的每次請求將沿用已創建服務

在這之后,我們便可以將服務通過構造函數注入或者是屬性注入的方式注入到Controller,View(通過使用@inject),甚至是Filter中(以前的項目是使用Unity將依賴注入到Filter,個人感覺不如.net core中注入的簡潔)。

3.構造函數獲取實例

        //數據訪問
        protected IBLLConstruct<UserInforMations> _repository { get; set; }
        //緩存
        protected ICacheContext _cache { get; set; }

        protected IAuth _auth { get; set; }

        public LoginService(IBLLConstruct<UserInforMations> repository, ICacheContext cache, IAuth auth)
        {
            this._cache = cache;
            this._repository = repository;
            this._auth = auth;
        }

流程大概就是這樣,我們啟動項目來看一下它的執行順序

(1)容器創建實例

(2)構造函數獲取實例

4.使用AutoFac實現擴展

除了ASP.NETCore自帶的IOC容器外,我們還可以使用其他成熟的DI框架,如Autofac,StructureMap等(本人只用過Unity,Autofac)。

 (1)安裝autofac

    

(2)創建容器並注冊依賴

修改Startup.cs中ConfigureServices方法 不要忘了將ConfigureServices的返回值修改為IServiceProvider 

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddDbContext<DirectSellContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DBContext"), b => b.UseRowNumberForPaging()));

            //使用AutoFac進行注入
            return new AutofacServiceProvider(AutofacExt.InitAutofac(services));

        }
(3)在AutofacExt類中創建容器並注冊依賴
        private static IContainer _container;
        public static IContainer InitAutofac(IServiceCollection services)
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<GuidTransientAppService>().As<IGuidTransientAppService>();
            builder.RegisterType<GuidScopedAppService>().As<IGuidScopedAppService>().InstancePerLifetimeScope();
            builder.RegisterType<GuidSingletonAppService>().As<IGuidSingletonAppService>().SingleInstance();

            builder.Populate(services);

            _container = builder.Build();
            return _container;

        }

InstancePerLifetimeScope:同一個Lifetime生成的對象是同一個實例


SingleInstance:單例模式,每次調用,都會使用同一個實例化的對象;每次都用同一個對象;


InstancePerDependency:默認模式,每次調用,都會重新實例化對象;每次請求都創建一個新的對象;

(4)AutoFac批量注冊服務

通過以上方式可以實現注入,但是我們每定義一個接口,都要在AutoFac中注冊一次,可以使用RegisterAssemblyTypes來避免這種重復勞動

反射獲取程序集

        /// <summary>
        /// 根據程序集名稱獲取程序集
        /// </summary>
        /// <param name="AssemblyName">程序集名稱</param>
        /// <returns></returns>
        public static Assembly GetAssemblyByName(String AssemblyName)
        {
            return Assembly.Load(AssemblyName);
        }

批量注冊

            //注冊Service中的對象,Service中的類要以Service結尾,否則注冊失敗
            builder.RegisterAssemblyTypes(GetAssemblyByName("MyProject.Domain")).
                Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();

這樣就實現了Domain層中以Service結尾的接口批量注冊 命名格式如下:

 

 

 


免責聲明!

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



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