使用反射在 .NET 依赖注入中动态注入通用接口和实现

问题描述 投票:0回答:1

我的 .NET (6,7,8) 库中有一个方法 (RegisterType),可以动态扫描并注册依赖项注入容器中的服务。它适用于非通用服务,但我正在努力使其适应通用服务。

这是现有的方法:

private static void RegisterType(IServiceCollection services, Type implementationType, ServiceLifetime serviceLifetime)
    {
        var implementedInterfaces = implementationType.GetInterfaces();
    
        if (implementedInterfaces.Length > 0)
        {
            foreach (var implementedInterface in implementedInterfaces)
            {
                services.Add(new ServiceDescriptor(implementedInterface, implementationType, serviceLifetime));
            }
        }
        else
        {
            services.Add(new ServiceDescriptor(implementationType, implementationType, serviceLifetime));
        }
    }

它与所有服务和存储库都能正常工作

现在,我想使用此方法来动态注入服务,例如:

public interface IBaseRepository<T> where T : BaseModel
public class BaseRepository<T> : IBaseRepository<T> where T : BaseModel

public interface IBaseRepository<T> where T : class
public class BaseRepository<T> : IBaseRepository<T> where T : class

如何动态处理此类通用场景?我想确保非通用和通用接口和实现都根据指定的生命周期正确注册。

更新1

我试过这个:

 // Handle generic interface
 var genericArguments = implementedInterface.GetGenericArguments().Select(g => g.BaseType).ToArray();
 var constructedInterface = implementedInterface.GetGenericTypeDefinition().MakeGenericType(genericArguments);

 // Handle generic type
 var genericTypeArguments = implementedInterface.GetGenericArguments().Select(g => g.BaseType).ToArray();
 var constructedType = implementationType.GetGenericTypeDefinition().MakeGenericType(genericTypeArguments);

 services.Add(new ServiceDescriptor(constructedInterface, constructedType, serviceLifetime));

但在 BaseModel 的情况下,它仅注册基本模型并且仅注册类 System.Object 例如,如果我的服务直接使用模型

public interface IBaseRepository<T> where T : CarModel
public class BaseRepository<T> : IBaseRepository<T> where T : CarModel

它有效,但这里没有泛型的好处

c# .net dependency-injection reflection
1个回答
0
投票

经过很多天的搜索,我通过将来自

GetGenericTypeDefinition()
的 GenericTypeDefinition 传递到服务
ServiceDescriptor
构造函数

找到了解决方案

更新代码

       private static void RegisterType(IServiceCollection services, Type implementationType, ServiceLifetime serviceLifetime)
       {
           var implementedInterfaces = implementationType.GetInterfaces();

           if (implementedInterfaces.Length > 0)
           {
               foreach (var implementedInterface in implementedInterfaces)
               {
                   if (implementedInterface.IsGenericType)
                   {
                       // Handle generic interface
                       var openGenericType = implementedInterface.GetGenericTypeDefinition();
                       services.Add(new ServiceDescriptor(openGenericType, implementationType, serviceLifetime));
                   }
                   else
                   {
                       services.Add(new ServiceDescriptor(implementedInterface, implementationType, serviceLifetime));
                   }
               }
           }
           else
           {
               //Generic & Non-generic type without interface
               services.Add(new ServiceDescriptor(implementationType, implementationType, serviceLifetime));
           }
       }

我仍然会关注这个问题,这个答案将在修复后更新

© www.soinside.com 2019 - 2024. All rights reserved.