.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

 

posted @ 2021-06-17 17:42  美女程序员-Joanna  阅读(499)  评论(0)    收藏  举报