• 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结尾的接口批量注册 命名格式如下:

     
  • 相关阅读:
    利用Python和webhook实现自动提交代码
    Python threading 单线程 timer重复调用函数
    Python requests 使用心得
    openresty实现接口签名安全认证
    使用jedis面临的非线程安全问题
    记一次线上升级openresty中kafka版本产生的多版本兼容问题
    mysql中走与不走索引的情况汇集(待全量实验)
    Elasticsearch深分页以及排序查询问题
    IO多路复用:Redis中经典的Reactor设计模式
    Netty在Dubbo中的使用过程源码分析
  • 原文地址:https://www.cnblogs.com/quebra/p/10203125.html
Copyright © 2020-2023  润新知