dotNet 整合 Microsoft.Extensions.DependencyInjection 利用反射实现依赖批量注入
前言
框架
.net 8.0
Microsoft.Extensions.DependencyInjection 8.0
创建三个类库项目
ConfigServices
LogServices
MailServices
创建一个控制台项目
ConsoleAppMail
ConfigServices
namespace ConfigServices.IService { public interface IConfigService { public string GetValue(string key); } }
namespace ConfigServices.IService { public class EnvVarConfigServiceImpl : IConfigService { public string GetValue(string key) { return Environment.GetEnvironmentVariable(key); } } }
LogServices
namespace LogServices.IService { public interface ILogProvider { public void LogInfo(string message); public void LogError(string message); } }
namespace LogServices.IService { public class LogProviderImpl : ILogProvider { public void LogInfo(string message) { Console.WriteLine($"INFO:{message}"); } public void LogError(string message) { Console.WriteLine($"ERROR:{message}"); } } }
MailServices
public interface IMailService { public void Send(string title, string to, string body); }
在邮件服务里面需要引用 LogProvider 和 ConfigService 在这里需要依赖项里面添加项目引用,在 Microsoft.Extensions.DependencyInjection 里面默认是采用构造函数注入,只需要在构造函数中编写就可以了,在创建对象的时候 DependencyInjection 框架会帮助我们实现依赖注入(DI)。
namespace MailServices.IService { public class MailServiceImpl : IMailService { private readonly ILogProvider log; private readonly IConfigService config; public MailServiceImpl(ILogProvider log, IConfigService config) { this.log = log; this.config = config; } public void Send(string title, string to, string body) { log.LogInfo("准备发送邮件"); string smtpServer = this.config.GetValue("smtpServer"); string username = this.config.GetValue("username"); string password = this.config.GetValue("password"); Console.WriteLine($"邮件服务器地址{smtpServer},{username},{password}"); Console.WriteLine("发邮件!"); log.LogInfo("邮件发送完成"); } } }
ConsoleAppMail
在控制台项目相当于我们的启动项, 需要告诉 DependencyInjection 框架那些类需要注入到容器中。
单个注入
单个注入比较麻烦,假如有100个service 就需要在Main 函数里面写100个,所以就有了通过反射的方式来批量注入。
using ConfigServices.IService; using LogServices.IService; using MailServices.IService; using Microsoft.Extensions.DependencyInjection; namespace ConsoleAppMail { internal class Program { static void Main(string[] args) { ServiceCollection services = new ServiceCollection(); services.AddScoped<ILogProvider,LogProviderImpl>(); services.AddScoped<IConfigService,EnvVarConfigServiceImpl>(); services.AddScoped<IMailService,MailServiceImpl>(); using (var sp = services.BuildServiceProvider()) { var mailService = sp.GetRequiredService<IMailService>(); mailService.Send("hello", "hshd@163.com", "你好 朋友"); } Console.ReadLine(); } } }
批量注入
通过反射可以批量读取程序集信息,将对应的接口和对应的实现类注入到IOC 容器中。
using Microsoft.Extensions.DependencyInjection; using System.Reflection; namespace ConsoleAppMail.util { public static class ServiceCollectionExtensions { /// <summary> /// 批量注册指定程序集中的所有实现了接口的类到 ServiceCollection /// </summary> /// <param name="services">ServiceCollection 实例</param> /// <param name="assembly">要扫描的程序集</param> public static IServiceCollection RegisterServicesFromAssembly(this IServiceCollection services, Assembly assembly) { var types = assembly.GetTypes() .Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any()); // 筛选出实现接口的类 foreach (var type in types) { var serviceInterface = type.GetInterfaces().FirstOrDefault(); if (serviceInterface != null) { services.AddScoped(serviceInterface, type); // 注册为 Scoped 生命周期 } } return services; } } }
static void Main(string[] args) { var assembly1 = Assembly.Load("ConfigServices"); var assembly2 = Assembly.Load("LogServices"); var assembly3 = Assembly.Load("MailServices"); ServiceCollection services = new ServiceCollection(); // 批量注册当前程序集中的服务 services.RegisterServicesFromAssembly(assembly1); services.RegisterServicesFromAssembly(assembly2); services.RegisterServicesFromAssembly(assembly3); using (var sp = services.BuildServiceProvider()) { var mailService = sp.GetRequiredService<IMailService>(); mailService.Send("hello", "hshd@163.com", "你好 朋友"); } Console.ReadLine(); }
通过该例子可以了解一哈 DependencyInjection 框架的基本使用方式,使用前需要了解一下依赖注入(DI)和IOC 容器的知识。
本文作者:茶凡_Matrix
本文链接:https://www.cnblogs.com/ChaFan/p/18527914
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2020-11-05 单片机最小系统实现LED灯闪烁