我的 .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
它有效,但这里没有泛型的好处
经过很多天的搜索,我通过将来自
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));
}
}
我仍然会关注这个问题,这个答案将在修复后更新