• ASP.NET Core 3.1默认DI使用以及使用autofac注入


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

    .netcore内置依赖注入,通过services.AddTransient、services.AddScoped、services.AddSingleton这些方法即可实现构造函数注入。

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

    Transient(瞬时的)

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

    Scoped(作用域的)

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

    Singleton(唯一的)

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

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

    //注册不同生命周期的服务
    services.AddTransient<ITestService, TestService>(); services.AddScoped<ITestService2, TestService2>(); services.AddSingleton<ITestService3, TestService3>();  

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

    Autofac可完美替换系统的依赖注入功能,可实现构造函数注入和属性注入,替换过程:

    在Program.cs 新增一行代码

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

    然后在Startup.cs 增加方法

             //集成Autofac
             public void ConfigureContainer(ContainerBuilder builder)
             {
                 //添加依赖注入实例,AutofacModuleRegister就继承自Autofac.Module的类
                 builder.RegisterModule(new StartupHelp.AutofacModuleRegister());
             }

    ConfigureAutofac 是自己封装的一个类  继承了 Autofac.Module

    其中注册类必须继承自Autofac.Module,并且在Load中实现注入,此处应用了程序集范围的注入以及单个对象的注入,最后添加的代码是为了支持控制器的属性注入。

    注入的接口(如IUnitOfWork)和实现(UnitOfWork)没有特别。

    注入对象的生命周期与.netcore内置的一致

    public class AutofacRegister : Autofac.Module
        {
            #region 单个类和接口
            //直接注册某一个类和接口
            //左边的是实现类,右边的As是接口
            //containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>().SingleInstance();
            //这里就跟默认DI差不多
            //services.AddScoped<TestServiceE, ITestServiceE>();
            #endregion
    
            #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 ITestServiceE _testService {get;set }
            //注意 上方为属性注入  发现为Null  需要在Startup.cs  的 ConfigureServices 方法下加入如下代码
            //services.AddControllers().AddControllersAsServices();
    
            //在控制器中使用属性依赖注入,其中注入属性必须标注为public
            //        var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
            //.Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
            //        containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
            #endregion
    
            /// <summary>
            /// 当前使用
            /// </summary>
            /// <param name="builder"></param>
            protected override void Load(ContainerBuilder builder)
            {
                //程序集范围注入 将匹配所有Service结尾的
                builder.RegisterAssemblyTypes(typeof(SysUserService).Assembly)
                     .Where(t => t.Name.EndsWith("Service"))
                     .AsImplementedInterfaces().PropertiesAutowired();
                //单个注册 工作单元 和数据库上下文
                builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().PropertiesAutowired();
                builder.RegisterType<dbContext>().As<DbContext>().PropertiesAutowired();
    
                //在控制器中使用属性依赖注入,其中注入属性必须标注为public  就是不需要通过构造函数 直接
                //public ITestServiceE _testService {get;set }   可直接_testService.方法  不许在构造函数接收
                //注意属性注入 发现为Null  需要在Startup.cs  的 ConfigureServices 方法下加入如下代码
                //services.AddControllers().AddControllersAsServices();
                var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
                .Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
                builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
            }
        }

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

    转载链接https://www.cnblogs.com/shenghuotaiai/p/12829694.html

    https://www.cnblogs.com/shenghuotaiai/p/12829694.html

  • 相关阅读:
    二维前缀和
    素数筛法
    dp-最大连续子序列的和
    dp-最长递增子序列 (LIS)
    dp-完全背包(题)
    dp-多重背包
    dp-完全背包
    DP-01背包 (题)
    DP- 01背包问题
    DP-直线分割递推
  • 原文地址:https://www.cnblogs.com/netlock/p/13359064.html
Copyright © 2020-2023  润新知