• .net core 3.1 使用autofac注入


    .net core 3.1 使用autofac注入

     

    在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期.

    微软给自行注入的服务,提供了3种生命周期.

    Transient(瞬时的)

     每次请求时都会创建的瞬时生命周期服务。这个生命周期最适合轻量级,无状态的服务。

    Scoped(作用域的)

    在同作用域,服务每个请求只创建一次。

    Singleton(唯一的)

    全局只创建一次,第一次被请求的时候被创建,然后就一直使用这一个.

    如何使用这三种生命周期呢?.我们直接在注入的时候用不同的方法就行了,代码如下:

    1
    2
    3
    services.AddTransient<ITestService, TestService>();
    services.AddScoped<ITestService2, TestService2>();
    services.AddSingleton<ITestService3, TestService3>();  

    自带的IOC 做一些小的项目完全没有问题,但是大项目使用起来就比较单一,所以我们将默认的IOC容器替换为Autofac

    .net core 2.x和3.x 使用autofac注入方式不一样,此文章是针对.net core 3.x

     首先,我们需要从nuget引用相关的包.

    Autofac.Extensions.DependencyInjection(这个包扩展了一些微软提供服务的类.来方便替换autofac)

    然后在Program.cs 新增一行代码

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

      

    然后在Startup.cs 增加方法

    1
    2
    3
    4
    public void ConfigureContainer(ContainerBuilder containerBuilder)
           {
               containerBuilder.RegisterModule<ConfigureAutofac>();
           }
    1
    ConfigureAutofac 是自己封装的一个类  继承了 Autofac.Module  也可以将以下代码直接写在这个方法里面:
    复制代码
     public class ConfigureAutofac : Autofac.Module
        {
            protected override void Load(ContainerBuilder containerBuilder)
            {
                //直接注册某一个类和接口
                //左边的是实现类,右边的As是接口
                //containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>().SingleInstance();
    
    
                #region 方法1   Load 适用于无接口注入
                //var assemblysServices = Assembly.Load("Exercise.Services");
    
                //containerBuilder.RegisterAssemblyTypes(assemblysServices)
                //          .AsImplementedInterfaces()
                //          .InstancePerLifetimeScope();
    
                //var assemblysRepository = Assembly.Load("Exercise.Repository");
    
                //containerBuilder.RegisterAssemblyTypes(assemblysRepository)
                //          .AsImplementedInterfaces()
                //          .InstancePerLifetimeScope();
    
                #endregion
    
                #region 方法2  选择性注入 与方法1 一样
                //            Assembly Repository = Assembly.Load("Exercise.Repository");
                //            Assembly IRepository = Assembly.Load("Exercise.IRepository");
                //            containerBuilder.RegisterAssemblyTypes(Repository, IRepository)
                //.Where(t => t.Name.EndsWith("Repository"))
                //.AsImplementedInterfaces().PropertiesAutowired();
    
                //            Assembly service = Assembly.Load("Exercise.Services");
                //            Assembly Iservice = Assembly.Load("Exercise.IServices");
                //            containerBuilder.RegisterAssemblyTypes(service, Iservice)
                //.Where(t => t.Name.EndsWith("Service"))
                //.AsImplementedInterfaces().PropertiesAutowired();
                #endregion
    
                #region 方法3  使用 LoadFile 加载服务层的程序集  将程序集生成到bin目录 实现解耦 不需要引用
                //获取项目路径
                var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
                var ServicesDllFile = Path.Combine(basePath, "Exercise.Services.dll");//获取注入项目绝对路径
                var assemblysServices = Assembly.LoadFile(ServicesDllFile);//直接采用加载文件的方法
                containerBuilder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces();
    
                var RepositoryDllFile = Path.Combine(basePath, "Exercise.Repository.dll");
                var RepositoryServices = Assembly.LoadFile(RepositoryDllFile);//直接采用加载文件的方法
                containerBuilder.RegisterAssemblyTypes(RepositoryServices).AsImplementedInterfaces();
                #endregion
    
    
                #region 在控制器中使用属性依赖注入,其中注入属性必须标注为public
                //在控制器中使用属性依赖注入,其中注入属性必须标注为public
                var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
    .Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
                containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
                #endregion
            }
        }
    复制代码

    注:业务逻辑层每个类都以Service结尾 如下截图:

     然后控制器通过构造函数注入,或者属性注入测试 如下:

     蓝色框为属性注入  发现为Null  需要在Startup.cs  的 ConfigureServices 方法下加入如下代码

    1
    services.AddControllers().AddControllersAsServices(); //控制器当做实例创建

    看到好的博文记录一下:

    https://www.cnblogs.com/diwu0510/p/11562248.html

    AutoFac中的方法说明:

    https://www.cnblogs.com/qtiger/p/13130802.html

  • 相关阅读:
    【vue开发问题-解决方法】(六)axios报错问题,Cannot read property 'protocol' of undefined
    【vue开发问题-解决方法】(五)vue Element UI 日期选择器获取日期格式问题 t.getTime is not a function
    【vue开发问题-解决方法】(四)vue Element UI使用中.$scopedSlots.default is not a function 报错
    【vue开发问题-解决方法】(三)axios拦截器,post请求问题处理,异步请求封装
    【vue开发问题-解决方法】(二)element UI日期控件失效RangeError:Maximum call stack size exceeded
    【vue开发问题-解决方法】(一)在style中设置background-image时路径问题
    异常分析
    如何理解spring MVC
    解决项目不编译4大clean
    java中的生产者模式
  • 原文地址:https://www.cnblogs.com/zxtceq/p/14156142.html
Copyright © 2020-2023  润新知