c# 批量注入示例代码

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. 像往常一样使用依赖注入来获取服务实例。

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

  

发表评论

评论已关闭。

相关文章