c# 批量注入示例代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Reflection;
 
// 自定义属性来标记服务类型
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false , Inherited = false )]
public class ServiceTypeAttribute : Attribute
{
     public ServiceLifetime Lifetime { get ; }
 
     public ServiceTypeAttribute(ServiceLifetime lifetime)
     {
         Lifetime = lifetime;
     }
}
 
public static class DependencyInjectionExtensions
{
     /// <summary>
     /// 批量注册服务
     /// </summary>
     /// <param name="services">IServiceCollection</param>
     /// <param name="servicePrefix">服务类的前缀,例如 "Service"</param>
     /// <param name="interfacePrefix">接口的前缀,例如 "I"</param>
     public static void RegisterServices( this IServiceCollection services, string servicePrefix, string interfacePrefix)
     {
         if (services == null )
         {
             throw new ArgumentNullException(nameof(services));
         }
 
         // 获取当前程序集中所有类
         var types = Assembly.GetExecutingAssembly().GetTypes();
 
         // 筛选出符合服务命名约定的类
         var serviceTypes = types
             .Where(t => t.Name.StartsWith(servicePrefix) && !t.IsInterface && !t.IsAbstract)
             .ToList();
 
         // 遍历所有服务类
         foreach ( var serviceType in serviceTypes)
         {
             // 尝试查找对应的接口
             var interfaceType = types.FirstOrDefault(t => t.Name == interfacePrefix + serviceType.Name.Substring(servicePrefix.Length) && t.IsInterface);
 
             if (interfaceType != null )
             {
                 // 获取服务类型上的 ServiceTypeAttribute
                 var serviceTypeAttribute = serviceType.GetCustomAttribute<ServiceTypeAttribute>();
                 var lifetime = serviceTypeAttribute?.Lifetime ?? ServiceLifetime.Scoped; // 默认使用 Scoped
 
                 // 根据不同的生命周期注册服务
                 switch (lifetime)
                 {
                     case ServiceLifetime.Singleton:
                         services.AddSingleton(interfaceType, serviceType);
                         break ;
                     case ServiceLifetime.Scoped:
                         services.AddScoped(interfaceType, serviceType);
                         break ;
                     case ServiceLifetime.Transient:
                         services.AddTransient(interfaceType, serviceType);
                         break ;
                     default :
                         services.AddScoped(interfaceType, serviceType); // 默认使用 Scoped
                         break ;
                 }
             }
             else
             {
                 // 如果没有找到对应的接口,则可以选择只注册服务本身,或者抛出异常
                 // 这里选择抛出异常,提示开发者需要有对应的接口
                 throw new InvalidOperationException($ "Service {serviceType.Name} does not have a corresponding interface (expected interface name: {interfacePrefix}{serviceType.Name.Substring(servicePrefix.Length)})" );
             }
         }
     }
}
 
// 示例接口和服务
public interface IUserService
{
     void DoSomething();
}
 
[ServiceType(ServiceLifetime.Scoped)] // 使用属性标记生命周期
public class UserService : IUserService
{
     public void DoSomething()
     {
         Console.WriteLine( "UserService.DoSomething() called." );
     }
}
 
public interface IOrderService
{
      void ProcessOrder();
}
 
[ServiceType(ServiceLifetime.Transient)]
public class OrderService: IOrderService
{
     public void ProcessOrder()
     {
         Console.WriteLine( "OrderService.ProcessOrder() called." );
     }
}
 
public class Program
{
     public static void Main( string [] args)
     {
         // 创建 ServiceCollection
         IServiceCollection services = new ServiceCollection();
 
         // 注册服务
         services.RegisterServices( "Service" , "I" );
 
         // 添加其他必要的服务,例如 MVC
         services.AddMvc(); // 如果是 ASP.NET Core MVC 项目
 
         // 构建 ServiceProvider
         IServiceProvider serviceProvider = services.BuildServiceProvider();
 
         // 从 ServiceProvider 中获取服务并使用
         var userService = serviceProvider.GetService<IUserService>();
         userService?.DoSomething();
 
         var orderService = serviceProvider.GetService<IOrderService>();
         orderService?.ProcessOrder();
         Console.ReadKey();
     }
}

代码说明

  1. ServiceTypeAttribute: 这是一个自定义属性,用于显式指定服务类的生命周期(Singleton、Scoped 或 Transient)。
  2. RegisterServices 扩展方法:
    • 它扩展了 IServiceCollection,提供了一个便捷的方法来批量注册服务。
    • servicePrefix 参数指定服务类的前缀(例如,"Service")。
    • interfacePrefix 参数指定接口的前缀(例如,"I")。
    • 它使用反射来查找程序集中所有符合命名约定的类(例如,以 "Service" 开头的类)。
    • 它假定接口的命名约定是接口前缀 + 服务类名(去掉服务前缀)。 例如,如果服务类是 UserService,则对应的接口应该是 IUserService
    • 它使用 GetCustomAttribute 方法获取服务类上的 ServiceTypeAttribute 属性,并根据属性中指定的生命周期注册服务。 如果未找到此属性,则默认使用 Scoped 生命周期。
    • 如果找不到与服务类对应的接口,它会抛出一个异常,指示缺少必需的接口。
  3. 示例:
    • IUserServiceUserService 演示了如何定义一个服务及其接口。
    • IOrderServiceOrderService 演示了另一个服务及其接口,并使用[ServiceType] 特性标记了生命周期
    • Main 方法中,我们创建了一个 ServiceCollection,调用 RegisterServices 方法注册服务,然后从 ServiceProvider 中解析并使用这些服务。

使用说明

  1. 定义您的服务接口和服务类,并确保它们遵循命名约定(例如,IUserServiceUserService)。
  2. 使用 ServiceTypeAttribute 属性标记您的服务类,以指定其生命周期。 如果省略此属性,则默认使用 Scoped 生命周期。
  3. 在您的应用程序的启动配置中(例如,Main 方法或 ConfigureServices 方法中),获取 IServiceCollection 的实例,并调用 RegisterServices 扩展方法,传递服务类前缀和接口前缀。
  4. 像往常一样使用依赖注入来获取服务实例。

这个方法提供了一种灵活且类型安全的方式来批量注册服务,并允许您通过属性显式控制每个服务的生命周期。

  

原创作者: wwwan 转载于: https://www.cnblogs.com/wwwan/p/18868271
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值