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

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

时间:2023-06-15 09:00:44浏览次数:51  
标签:Autofac builder 多层 class cs typeof NET7 public 注入

一、配置Autofac替换内置DI

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

 

2.Program.cs中加上

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

 

 

二、构造函数注入

 新建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();

 注入试下是否注入成功

 调用成功,证明注入成功

 

三、属性注入

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());

 验证:

 成功。

四、批量注入

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

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

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

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

 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改成

 

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的代码变成

 

五、手动获取实例

手动获取实例的场景有静态帮助类中获取实例,例如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中增加

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

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

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

六、其它用法

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

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

 

 2.一接口多实现

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

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

 

TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back

标签:Autofac,builder,多层,class,cs,typeof,NET7,public,注入
From: https://www.cnblogs.com/wei325/p/17481596.html

相关文章

  • .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......
  • net7下的tcpip示例
    2023-05-27测试,直接用百度文心一言搜索的,结果出来的代码能运行得通,不错不错服务器端: usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;namespacetcpipdemo_server;classProgram{staticvoidMain(string[]args){//创建TCP......
  • 多层感知机的梯度推导
    多层感知机的梯度推导pytorch实现注:torch.randn(m,n)生成m行n列的随机数......
  • week13_MLP_多层感知机
    Multi-LayerPerceptron多层感知机生物神经网络圣地亚哥·拉蒙-卡哈尔(西班牙语:SantiagoRamónyCajal,1852年5月1日-1934年10月17日),西班牙病理学家、组织学家,神经学家,1906年诺贝尔生理学医学奖得主。人类对大脑的研究由来已久,在十九世纪末到二十世纪初,在大脑神经系统的研究方......
  • 动手学深度学习(三) 多层感知机
    多层感知机多层感知机的基本知识使用多层感知机图像分类的从零开始的实现使用pytorch的简洁实现多层感知机的基本知识深度学习主要关注多层模型。在这里,我们将以多层感知机(multilayerperceptron,MLP)为例,介绍多层神经网络的概念。隐藏层下图展示了一个多层感知机的神经网络图,它含有......