编辑
2025-09-18
C#
00

目录

🔥 传统手动注册的三大痛点
😵 痛点1:重复性劳动,效率低下
😱 痛点2:容易遗漏,运行时才报错
🤯 痛点3:维护成本高,代码冗余
✨ 自动注册方案:反射的魅力
🎯 核心思路
🛠️ 实现策略
💻 完整代码实战演示
📋 服务接口定义(IServices.cs)
🏗️ 服务实现类(Services.cs)
业务逻辑处理类(BusinessLogic)
🚀 自动注册核心代码(Program.cs)
🎯 运行效果展示
⚠️ 重要注意事项
🚨 性能考虑
🔒 安全提醒
📝 命名约定
💝 实战收获总结

你是否也有过这样的经历:每次新增一个服务,都要跑到Program.cs里手动添加一行services.AddScoped<IUserService, UserService>()?项目越来越大,服务越来越多,光是维护这些注册代码就让人头疼不已...

手动管理依赖注入是最耗时的重无聊工作之一。今天,我们就来彻底解决这个问题!

说到根上就是放射扫描程序集,这块与spring的扫包一回事。

本文将带你掌握C#服务自动注册技术,让你的代码从此告别重复劳动,实现真正的优雅开发。

🔥 传统手动注册的三大痛点

😵 痛点1:重复性劳动,效率低下

每新增一个服务,就要手动写一行注册代码:

C#
services.AddScoped<IUserService, UserService>(); services.AddScoped<IOrderService, OrderService>(); services.AddScoped<IEmailService, EmailService>(); // 几十个服务下来,手都要写麻了...

😱 痛点2:容易遗漏,运行时才报错

新同事加入项目,新增了服务但忘记注册,编译没问题,一运行就炸:

C#
System.InvalidOperationException: Unable to resolve service for type 'INewService'

🤯 痛点3:维护成本高,代码冗余

随着项目发展,Program.cs中的注册代码越来越多,可读性急剧下降,维护起来苦不堪言。

✨ 自动注册方案:反射的魅力

🎯 核心思路

利用反射机制,扫描指定命名空间下的所有类型,根据预设规则自动完成服务注册。简单来说,就是让程序"自己发现"需要注册的服务。

🛠️ 实现策略

  1. 扫描程序集:找到所有服务类
  2. 智能匹配:自动识别接口和实现类的对应关系
  3. 灵活注册:有接口按接口注册,无接口直接注册

💻 完整代码实战演示

让我们看看这个"神器"是如何工作的:

📋 服务接口定义(IServices.cs)

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AppAutoDI.Services { // ==================== 服务接口定义 ==================== public interface IUserService { Task<string> GetUserAsync(int id); Task CreateUserAsync(string name); } public interface IOrderService { Task<string> ProcessOrderAsync(int orderId); Task<decimal> CalculateTotalAsync(int orderId); } public interface IEmailService { Task SendEmailAsync(string to, string subject, string body); } public interface ILoggerService { void LogInfo(string message); void LogError(string message); } }

🏗️ 服务实现类(Services.cs)

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AppAutoDI.Services { // ==================== 服务实现类 ==================== public class UserService : IUserService { private readonly ILogger<UserService> _logger; public UserService(ILogger<UserService> logger) { _logger = logger; } public async Task<string> GetUserAsync(int id) { _logger.LogInformation($"获取用户信息,ID: {id}"); await Task.Delay(100); // 模拟异步操作 return $"用户{id}: 张三"; } public async Task CreateUserAsync(string name) { _logger.LogInformation($"创建用户: {name}"); await Task.Delay(50); } } public class OrderService : IOrderService { private readonly ILogger<OrderService> _logger; public OrderService(ILogger<OrderService> logger) { _logger = logger; } public async Task<string> ProcessOrderAsync(int orderId) { _logger.LogInformation($"处理订单,ID: {orderId}"); await Task.Delay(200); return $"订单{orderId}处理完成"; } public async Task<decimal> CalculateTotalAsync(int orderId) { _logger.LogInformation($"计算订单总价,ID: {orderId}"); await Task.Delay(100); return 299.99m; } } public class EmailService : IEmailService { private readonly ILogger<EmailService> _logger; public EmailService(ILogger<EmailService> logger) { _logger = logger; } public async Task SendEmailAsync(string to, string subject, string body) { _logger.LogInformation($"发送邮件到: {to}, 主题: {subject}"); await Task.Delay(300); } } public class LoggerService : ILoggerService { private readonly ILogger<LoggerService> _logger; public LoggerService(ILogger<LoggerService> logger) { _logger = logger; } public void LogInfo(string message) { _logger.LogInformation(message); } public void LogError(string message) { _logger.LogError(message); } } // 无接口的独立服务类 public class ReportService { private readonly ILogger<ReportService> _logger; public ReportService(ILogger<ReportService> logger) { _logger = logger; } public async Task<string> GenerateReportAsync() { _logger.LogInformation("生成报告中..."); await Task.Delay(500); return "月度销售报告已生成"; } } // 数据处理服务(无接口) public class DataProcessingService { private readonly ILogger<DataProcessingService> _logger; public DataProcessingService(ILogger<DataProcessingService> logger) { _logger = logger; } public async Task ProcessDataAsync() { _logger.LogInformation("处理数据中..."); await Task.Delay(300); } } }

业务逻辑处理类(BusinessLogic)

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AppAutoDI.Services; namespace AppAutoDI { // ==================== 业务逻辑处理类 ==================== public class BusinessLogic { private readonly IUserService _userService; private readonly IOrderService _orderService; private readonly IEmailService _emailService; private readonly AppAutoDI.Services.ReportService _reportService; private readonly AppAutoDI.Services.DataProcessingService _dataProcessingService; public BusinessLogic( IUserService userService, IOrderService orderService, IEmailService emailService, AppAutoDI.Services.ReportService reportService, AppAutoDI.Services.DataProcessingService dataProcessingService) { _userService = userService; _orderService = orderService; _emailService = emailService; _reportService = reportService; _dataProcessingService = dataProcessingService; } public async Task RunBusinessLogicAsync() { Console.WriteLine("🚀 开始执行业务逻辑...\n"); // 用户服务操作 Console.WriteLine("📱 用户服务操作:"); await _userService.CreateUserAsync("李四"); var user = await _userService.GetUserAsync(1001); Console.WriteLine($"获取用户结果: {user}\n"); // 订单服务操作 Console.WriteLine("🛒 订单服务操作:"); var orderResult = await _orderService.ProcessOrderAsync(2001); var total = await _orderService.CalculateTotalAsync(2001); Console.WriteLine($"订单处理结果: {orderResult}"); Console.WriteLine($"订单总价: ¥{total}\n"); // 邮件服务操作 Console.WriteLine("📧 邮件服务操作:"); await _emailService.SendEmailAsync("user@example.com", "订单确认", "您的订单已确认"); Console.WriteLine(); // 报告服务操作 Console.WriteLine("📊 报告服务操作:"); var report = await _reportService.GenerateReportAsync(); Console.WriteLine($"报告结果: {report}\n"); // 数据处理服务操作 Console.WriteLine("🔄 数据处理服务操作:"); await _dataProcessingService.ProcessDataAsync(); Console.WriteLine("数据处理完成\n"); Console.WriteLine("✅ 业务逻辑执行完成!"); } } }

🚀 自动注册核心代码(Program.cs)

C#
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.Reflection; namespace AppAutoDI { internal class Program { public static async Task Main(string[] args) { Console.OutputEncoding = System.Text.Encoding.UTF8; Console.WriteLine("🎯 自动服务注册演示程序"); // 创建Host建造器 var hostBuilder = Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { // 🔧 自动注册服务 RegisterServices(services); // 注册业务逻辑类 services.AddScoped<BusinessLogic>(); }); // 构建并运行Host using var host = hostBuilder.Build(); // 获取服务并执行业务逻辑 using var scope = host.Services.CreateScope(); var businessLogic = scope.ServiceProvider.GetRequiredService<BusinessLogic>(); try { await businessLogic.RunBusinessLogicAsync(); } catch (Exception ex) { Console.WriteLine($"❌ 执行出错: {ex.Message}"); } Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); } /// <summary> /// 基础版自动服务注册 - 简单高效 /// </summary> /// <param name="services">服务集合</param> private static void RegisterServices(IServiceCollection services) { Console.WriteLine("🔧 开始自动注册服务...\n"); try { // 🔍 加载指定程序集 var assembly = Assembly.GetExecutingAssembly(); // 使用当前程序集 // 🎯 筛选服务类型:排除接口和抽象类 var serviceTypes = assembly.GetTypes() .Where(type => type.Namespace != null && type.Namespace.Contains("AppAutoDI.Services") && !type.IsInterface && !type.IsAbstract); int registeredCount = 0; foreach (var serviceType in serviceTypes) { // 🔗 获取当前类型实现的接口 var interfaces = serviceType.GetInterfaces() .Where(i => i.Namespace != null && i.Namespace.Contains("AppAutoDI.Services")); // ⚡ 注册策略:无接口直接注册,有接口按接口注册 if (!interfaces.Any()) { services.AddScoped(serviceType); Console.WriteLine($"✅ 已注册服务: {serviceType.Name}"); registeredCount++; } else { foreach (var interfaceType in interfaces) { services.AddScoped(interfaceType, serviceType); Console.WriteLine($"✅ 已注册服务: {interfaceType.Name} -> {serviceType.Name}"); registeredCount++; } } } Console.WriteLine($"\n🎉 服务注册完成!共注册 {registeredCount} 个服务\n"); } catch (Exception ex) { Console.WriteLine($"❌ 服务注册失败: {ex.Message}"); throw; } } } }

🎯 运行效果展示

image.png

⚠️ 重要注意事项

🚨 性能考虑

反射操作在应用启动时执行一次,对运行时性能几乎无影响。但如果服务数量巨大(>1000个),建议考虑更高级的方案。

🔒 安全提醒

确保只扫描可信的程序集和命名空间,避免意外注册不安全的类型。

📝 命名约定

建议遵循 IXxxService + XxxService 的命名模式,这样自动匹配会更准确。

💝 实战收获总结

通过本文的学习,你已经掌握了:

  1. 核心技能:使用反射实现服务自动注册,告别重复性手动配置
  2. 最佳实践:智能识别接口与实现类的对应关系,支持多种注册策略
  3. 生产应用:完整可用的代码模板,可直接应用于实际项目开发

这套自动注册方案能让你的开发效率提升50%以上,尤其在大型项目中效果更加明显。从此告别繁琐的手动注册,让代码变得更加优雅和易维护!


🤔 互动话题

  1. 你在项目中还遇到过哪些重复性的配置工作?
  2. 对于微服务架构,你觉得这套方案还需要哪些改进?

💡 如果这篇文章对你有帮助,请转发给更多的.NET开发同行,让我们一起写出更优雅的代码!

🔥 想了解更多C#实战技巧?关注我的公众号,每周分享实用的编程干货!

相关信息

通过网盘分享的文件:AppAutoDI.zip 链接: https://pan.baidu.com/s/1JFgj1jZMFr-v-0LJM8Rr-g 提取码: tqcd --来自百度网盘超级会员v9的分享

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!