.Net Core3.1 Autofac实现构造函数依赖注入
1、通过nuget下载安装如下截图所示的Nuget程序包

2、如下所示,修改Progam中的CreateHostBuilder方法,使用autofac的容器工厂替换系统默认的容器:

1 public class Program 2 { 3 /// <summary> 4 /// 5 /// </summary> 6 /// <param name="args"></param> 7 public static void Main(string[] args) 8 { 9 CreateHostBuilder(args).Build().Run(); 10 } 11 12 /// <summary> 13 /// 14 /// </summary> 15 /// <param name="args"></param> 16 /// <returns></returns> 17 public static IHostBuilder CreateHostBuilder(string[] args) => 18 Host.CreateDefaultBuilder(args) 19 .UseServiceProviderFactory(new AutofacServiceProviderFactory()) //使用autofac的容器工厂替换系统默认的容器 20 .ConfigureWebHostDefaults(webBuilder => 21 { 22 webBuilder.UseStartup<Startup>(); 23 }).UseNLog(); //使用NLog 24 }
3、在Startup类中增加一个方法ConfigureContainer,配置Auto fac Container
1 /// <summary> 2 /// Autofac动态注入所有含有 [Services]标签的服务 3 /// </summary> 4 /// <param name="builder"></param> 5 public void ConfigureContainer(ContainerBuilder builder) 6 { 7 builder.RegisterAssemblyTypes(DependencyUtilities.GetReferencedAssemblies()) 8 .Where(type => type.GetCustomAttribute<ServicesAttribute>() != null) 9 .AsImplementedInterfaces() 10 .AsSelf() 11 .InstancePerLifetimeScope(); 12 13 }
4、定义一个标记性特性类 【ServicesAttribute】

1 namespace NetCoreWebApi.Repository.DependencyAttribute 2 { 3 /// <summary> 4 /// 自定义依赖注入自定义特性 5 /// </summary> 6 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] 7 public class ServicesAttribute:Attribute 8 { 9 } 10 }
5、 利用反射加载需要注入的dll程序集

1 public static class DependencyUtilities 2 { 3 const string pattern = "^Microsoft.\\w*|^System.\\w*|^Newtonsoft.\\w*|^Autofac.\\w*|^Serilog.\\w*|^App.\\w*|^runtime.\\w*|^Google.\\w*|^IdentityServer4.\\w*"; 4 5 public static Assembly[] GetReferencedAssemblies() 6 { 7 Regex relatedRegex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); 8 return DependencyContext.Default.RuntimeLibraries 9 .Where(item => !relatedRegex.IsMatch(item.Name)) 10 .SelectMany(item => item.GetDefaultAssemblyNames(DependencyContext.Default)) 11 .Select(item => Assembly.Load(item)) 12 .ToArray(); 13 } 14 }
6、从加载的程序集中获取到含有 [Services]标签的程序集,然后创建对象

1 /// <summary> 2 /// Autofac动态注入所有含有 [Services]标签的服务 3 /// </summary> 4 /// <param name="builder"></param> 5 public void ConfigureContainer(ContainerBuilder builder) 6 { 7 builder.RegisterAssemblyTypes(DependencyUtilities.GetReferencedAssemblies()) 8 .Where(type => type.GetCustomAttribute<ServicesAttribute>() != null) 9 .AsImplementedInterfaces() 10 .AsSelf() 11 .InstancePerLifetimeScope(); 12 13 }
7、依赖构造函数注入实例代码如下
1 [Route("api/[controller]/[Action]")] 2 [ApiController] 3 // [RequestFilter] 不能直接放置在这,原因RequestFilter过滤器中需要注入ILogger 4 [TypeFilter(typeof(RequestFilterAttribute))] 5 6 public class SystemMembersController : BaseController 7 { 8 private readonly ILogger<SystemMembersController> _logger; 9 private readonly SystemLogServices _systemLogServices; 10 11 /// <summary> 12 /// 1、该类依赖 SystemLogServices 类,所以在SystemLogServices类上面需要标记自定义的标记注入特性 [Services] 13 /// 2、AutoFac 通过识别特性动态注入含有[service]标签的服务 14 /// </summary> 15 /// <param name="logger"></param> 16 /// <param name="systemLogServices"></param> 17 public SystemMembersController(ILogger<SystemMembersController> logger, SystemLogServices systemLogServices) 18 { 19 _logger = logger; 20 _systemLogServices = systemLogServices; 21 } 22 /// <summary> 23 /// 测试IOC依赖注入 24 /// </summary> 25 [HttpGet] 26 public void TestIOC() 27 { 28 _systemLogServices.InsertLog(); 29 } 30 }
1 namespace NetCoreWebApi.Services.Services.SystemLog 2 { 3 [Services] 4 public class SystemLogServices 5 { 6 private readonly Ofcp_Log_GlobalLogRepository _Log_GlobalLogRepository; 7 private readonly ILogger<SystemLogServices> _logger; 8 9 /// <summary> 10 /// 该类又依赖于Ofcp_Log_GlobalLogRepository,所以在该类又依赖于Ofcp_Log_GlobalLogRepository类上面需要标记自定义的标记注入特性 [Services] 11 /// </summary> 12 /// <param name="log_GlobalLogRepository"></param> 13 /// <param name="logger"></param> 14 public SystemLogServices(Ofcp_Log_GlobalLogRepository log_GlobalLogRepository, ILogger<SystemLogServices> logger) 15 { 16 _Log_GlobalLogRepository = log_GlobalLogRepository; 17 _logger = logger; 18 } 19 20 public void InsertLog() 21 { 22 try 23 { 24 var Log = new Marketing_Log_ProcessUpdate 25 { 26 Guid = Guid.NewGuid().ToString(), 27 ApiUrl = "api/InsertLog", 28 Extension = "InsertLog日志测试" 29 30 }; 31 _Log_GlobalLogRepository.Client.Insertable<Ofcp_Log_GlobalLog>(Log).IgnoreColumns(true,false).ExecuteCommand(); 32 } 33 catch (Exception ex) 34 { 35 _logger.LogError("InsertLog写入失败", ex.Message); 36 } 37 } 38 39 } 40 }
1 namespace NetCoreWebApi.Repository.Respository 2 { 3 /// <summary> 4 /// 5 /// </summary> 6 [Services] 7 public class Ofcp_Log_GlobalLogRepository:BaseRepository<Ofcp_Log_GlobalLog> 8 { 9 public Ofcp_Log_GlobalLogRepository(IDbClientFactory clientFactory):base(clientFactory) 10 { 11 12 } 13 } 14 }
8、运行结果及测试
1、调用SystemMembersController控制器的TestIOC方法时,由于SystemMembersController控制器依赖于SystemLogServices类,所以程序首先调用SystemLogServices类的构造函数,初始化对象
2、初始化SystemLogServices对象时,检测到SystemLogServices又依赖于Ofcp_Log_GlobalLogRepository。程序调用Ofcp_Log_GlobalLogRepository的构造函数初始化对象
3、所以,在调用SystemMembersController控制器的方法时,程序先构造Ofcp_Log_GlobalLogRepository对象,构造完成后再构造SystemLogServices,最后才构造SystemMembersController



浙公网安备 33010602011771号