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

一、配置Autofac替换内置DI

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

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

 

2.Program.cs中加上

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

 

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

 

二、构造函数注入

 新建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依赖注入整合多层,项目中可直接用

 注入试下是否注入成功

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

 调用成功,证明注入成功

 

三、属性注入

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依赖注入整合多层,项目中可直接用

 验证:

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

 成功。

四、批量注入

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

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依赖注入整合多层,项目中可直接用

 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依赖注入整合多层,项目中可直接用

 

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依赖注入整合多层,项目中可直接用

 

五、手动获取实例

手动获取实例的场景有静态帮助类中获取实例,例如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依赖注入整合多层,项目中可直接用

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

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

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

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

六、其它用法

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

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

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

 

 2.一接口多实现

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

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

 

 

Enable collaborative features and customize widget: Bing Webmaster Portal

举报
发表评论

评论已关闭。

相关文章

当前内容话题
  • 0