首页 > 其他分享 >.NET7 中Autofac依赖注入整合多层,项目中可直接用

.NET7 中Autofac依赖注入整合多层,项目中可直接用

时间:2023-06-18 16:38:05浏览次数:41  
标签:Autofac builder 多层 class cs typeof NET7 public 注入

一、配置Autofac替换内置DI

1.安装Nuget包:Autofac.Extensions.DependencyInjection

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Ioc/DI

 

2.Program.cs中加上

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //在这里写注入代码
    
});

 

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Ioc/DI_02

 

二、构造函数注入

 新建IUserService,类UserService

public interface IUserService
    {
        public string GetUserName();
    }
public class UserService:IUserService
    {
        public string GetUserName()
        {
            return "张三";
        }
    }

在上面的ConfigureContainer方法把UserService注入进来,默认是瞬时注入

瞬时注入:containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerDependency();;

单例注入:containerBuilder.RegisterType<UserService>().As<IUserService>().SingleInstance();

生命周期注入: containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Assembly_03

 注入试下是否注入成功

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Ioc/DI_04

 调用成功,证明注入成功

 

三、属性注入

1.把HomeController改成属性注入形式,属性注入有一个问题,就是那些属性需要注入?全部注入没必要,父类也有很多属性,要按需注入,给属性增加一个自定义特性标识说明需要注入。

public class HomeController : Controller
    {
        [AutowiredProperty]
        private IUserService userService { get; set; }
        public IActionResult Index()
        {
            string name = userService.GetUserName();
              return View();
        }
    }

2.新增自定义特性类AutowiredPropertyAttribute.cs

[AttributeUsage(AttributeTargets.Property)]//为了支持属性注入,只能打到属性上
    public class AutowiredPropertyAttribute: Attribute
    {
    }

3.增加识别特性类AutowiredPropertySelector.cs

public class AutowiredPropertySelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            //判断属性的特性是否包含自定义的属性,标记有返回true
            return propertyInfo.CustomAttributes.Any(s => s.AttributeType == typeof(AutowiredPropertyAttribute));
        }
    }

4.因为Controller 默认是由 Mvc 模块管理的,需要把控制器放到IOC容器中,在Program.cs中增加

//让控制器实例由容器创建
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

5.把容器注册到IOC容器,在Program.cs的ConfigureContainer()增加

//获取所有控制器类型并使用属性注入
    Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
        .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
    containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Ioc/DI_05

 验证:

.NET7 中Autofac依赖注入整合多层,项目中可直接用_自定义_06

 成功。

四、批量注入

实际项目中那么多需要注入的类,一个个写注册就不太现实了,需要一个可以批量注入的方法。

1.新建三个空接口IScopeDenpendency.cs,ISingletonDenpendency.cs,ITransitDenpendency.cs

/// <summary>
    /// 瞬时注入
    /// </summary>
    public interface ITransitDenpendency
    {
    }
  /// <summary>
    /// 单例注入标识
    /// </summary>
    public interface ISingletonDenpendency
    {
    }
   /// <summary>
    /// 生命周期注入标识
    /// </summary>
    public interface IScopeDenpendency
    {
    }

2.把上面要注入的类实现上面的接口

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Assembly_07

 3.新增一个IocManager类

/// <summary>
    /// Ioc管理
    /// </summary>
    public static class IocManager
    {
        /// <summary>
        /// 批量注入扩展
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="assembly"></param>
        public static void BatchAutowired(this ContainerBuilder builder, Assembly assembly)
        {

            var transientType = typeof(ITransitDenpendency); //瞬时注入
            var singletonType = typeof(ISingletonDenpendency); //单例注入
            var scopeType = typeof(IScopeDenpendency); //单例注入
            //瞬时注入
            builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(transientType))
                .AsSelf()
                .AsImplementedInterfaces()
                .InstancePerDependency()
                .PropertiesAutowired(new AutowiredPropertySelector());
            //单例注入
            builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(singletonType))
               .AsSelf()
               .AsImplementedInterfaces()
               .SingleInstance()
               .PropertiesAutowired(new AutowiredPropertySelector());
            //生命周期注入
            builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(scopeType))
               .AsSelf()
               .AsImplementedInterfaces()
               .InstancePerLifetimeScope()
               .PropertiesAutowired(new AutowiredPropertySelector());

        }

4.把注入类ConfigureContainer改成

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Assembly_08

 

5.防止Program.cs代码过多,建一个Module把注入代码搬走,新建AutofacRegisterModule.cs类把ConfigureContainer的代码移过去

public class AutofacRegisterModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {

            //获取所有控制器类型并使用属性注入
            Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
                .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
            builder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());
            //批量自动注入,把需要注入层的程序集传参数,注入Service层的类
            builder.BatchAutowired(typeof(UserService).Assembly);
            //注入其它层的containerBuilder.BatchAutowired(typeof(其它层的任务一个类).Assembly);
        }
    }

ConfigureContainer的代码变成

.NET7 中Autofac依赖注入整合多层,项目中可直接用_属性注入_09

 

五、手动获取实例

手动获取实例的场景有静态帮助类中获取实例,例如redisHelper中获取注入的配置文件中的连接字符串

1.在上面的IocManager类中增加

private static object obj = new object();
 private static ILifetimeScope _container { get; set; }

  public static void InitContainer(ILifetimeScope container)
        {
            //防止过程中方法被调用_container发生改变
            if (_container == null)
            {
                lock (obj)
                {
                    if (_container == null)
                    {
                        _container = container;
                    }
                }
            }
        }
        /// <summary>
        /// 手动获取实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Resolve<T>()
        {
            return _container.Resolve<T>();
        }

2.在Program.cs中增加

.NET7 中Autofac依赖注入整合多层,项目中可直接用_自定义_10

 3.验证,新建一个DataHelper.cs类

public class DataHelper
    {
        //手动注入UserService
        private static IUserService userService = IocManager.Resolve<IUserService>();
        public static string GetData()
        {
            return userService.GetUserName();
        }
    }

.NET7 中Autofac依赖注入整合多层,项目中可直接用_自定义_11

 成功获取到值,证明从容器中获取成功。

六、其它用法

1.不用接口,直接注入实例

public class UserService :ITransitDenpendency
    {
        public string GetUserName()
        {
            return "张三";
        }
    }

.NET7 中Autofac依赖注入整合多层,项目中可直接用_属性注入_12

 

 2.一接口多实现

public class UserService :IUserService
    {
        public string GetUserName()
        {
            return "张三";
        }
    }

 public class UserService2 : IUserService
    {
        public string GetUserName()
        {
            return "张三2号";
        }
    }

.NET7 中Autofac依赖注入整合多层,项目中可直接用_Assembly_13

 


标签:Autofac,builder,多层,class,cs,typeof,NET7,public,注入
From: https://blog.51cto.com/u_12117371/6508736

相关文章

  • TensorFlow05.3 神经网络反向传播算法-多层感知机梯度(理论知识)
    首先这个是链式法则:如果扩展到多层感知机的话:我们在学这个的时候首先知道一个东西:所以这个整体的步骤就是:1.2.3.......
  • .Net7发现System.Numerics.Vector矢量化的一个bug,Issues给了dotnet团队
    因为前几天做.Net7的矢量化性能优化,发现了一个bug。在类System.Numerics.Vector里面的成员变量IsHardwareAccelerated。但是实际上不确定这个bug是visualstudio2022的还是System.Numerics.Vector库的,个人认为应该是前者,也就是vs的bug。Vector.IsHardwareAccelerated返回的是Tr......
  • .NET7 中Autofac依赖注入整合多层,项目中可直接用
    目录一、配置Autofac替换内置DI二、构造函数注入三、属性注入四、批量注入五、手动获取实例六、其它用法1.不用接口,直接注入实例 2.一接口多实现 回到顶部一、配置Autofac替换内置DI1.安装Nuget包:Autofac.Extensions.DependencyInjection 2.Program.cs......
  • .NET7 中Autofac依赖注入整合多层,项目中可直接用
    一、配置Autofac替换内置DI1.安装Nuget包:Autofac.Extensions.DependencyInjection 2.Program.cs中加上builder.Host.UseServiceProviderFactory(newAutofacServiceProviderFactory());builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder=>{//在......
  • .Net7基础类型的优化和循环克隆优化
    前言.Net7里面对于基础类型的优化,是必不可少的。因为这些基础类型基本上都会经常用到,本篇除了基础类型的优化介绍之外,还有一个循环克隆的优化特性,也一并看下。概括1.基础类型优化基础类型的优化不会有些不会涉及ASM,主要是记忆。一:double.Parse和float.Parse,把某数值转换成d......
  • .Net7矢量化的性能优化
    前言矢量化是性能优化的重要技术,也是寄托硬件层面的优化技术。本篇来看下。概括一:矢量化支持的问题:矢量化的System.Runtime.Intrinsics.X86.Sse2.MoveMask函数和矢量化的Vector128.Create().ExtractMostSignificantBits()函数返回的结果是一样的。但是前者只能在支持SSE2的......
  • 多层螺旋CT行业市场现状研究及未来前景分析报告
    2023-2029全球多层螺旋CT行业调研及趋势分析报告2022年全球多层螺旋CT市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。多层螺旋CT可以对全身组织器官进行检查,比如头部、颈部、胸部、腹部、盆腔......
  • 多层网关已成过去,网关多合一成潮流,网关改造正当时丨Higress 正式发布 1.0 版本
    作者:Higress团队01前言K8s通过Ingress/GatewayAPI将网关标准化,逐步将安全网关、流量网关、微服务网关内聚,解决从单体到微服务到云原生多层网关的复杂度,合久必分,分久必合,多层网关已成过去,网关多合一成潮流,成为K8s开发者和微服务开发者共同关心的话题。02Higress1.0正式......
  • 多层网关已成过去,网关多合一成潮流,网关改造正当时丨Higress 正式发布 1.0 版本
    作者:Higress团队01前言K8s通过Ingress/GatewayAPI将网关标准化,逐步将安全网关、流量网关、微服务网关内聚,解决从单体到微服务到云原生多层网关的复杂度,合久必分,分久必合,多层网关已成过去,网关多合一成潮流,成为K8s开发者和微服务开发者共同关心的话题。02Higress1.0......
  • Pytorch高级api搭建多层感知机实战
    Pytorch高级api搭建多层感知机实战代码importtorchimporttorch.nn.functionalasFimporttorch.optimasoptimfromtorchvisionimportdatasets,transformsbatch_size=200learning_rate=0.01epochs=10train_loader=torch.utils.data.DataLoader(da......