C#依赖注入相同Generic Type的多个实现
Posted
技术标签:
【中文标题】C#依赖注入相同Generic Type的多个实现【英文标题】:C# dependency injection multiple implementation of the same Generic Type 【发布时间】:2021-01-18 15:06:53 【问题描述】:注意:这不是重复的!
我有以下示例:
public interface IRepository<TEntity> where TEntity : IEntity
...
public class Repository<TEntity> : IRepository<TEntity> where TEntity : IEntity
...
public class Repository<SpecialClass> : IRepository<SpecialClass>
...
public class SpecialClass: IEntity
...
现在我想为每个IRepository<>
使用Repository<>
类,IRepository<SpecialClass>
除外:
// every IRepository<> :
services.AddScoped(typeof(IRepository<>), typeof(RepositoryEFCore<>));
// but not for SpecialClass
services.AddScoped(typeof(IRepository<SpecialClass>), typeof(Repository<SpecialClass>));
问题是我如何为同一个接口注册两个(或多个)不同的类,而该接口已经为另一个类注册了?
【问题讨论】:
切换注册顺序,看看是否有效。先注册特例。我还假设这是使用默认的内置容器。 @Nkosi,我怀疑切换顺序会很重要。如果我错了,请纠正我。 我似乎没有明白你的问题。在我看来,您的代码似乎已经完成了您想要的操作。如果您使用的是默认 DI,那么订单就像@Nkosi 所说的那样重要。如果您先注册通用,然后注册特定,当您解析IRepository<SpecialClass>
时,DI 会注入最后添加的服务,在您的情况下为 Repository<SpecialClass>
。
【参考方案1】:
services.AddScoped(typeof(IRepository<>), typeof(RepositoryEFCore<>));
此行将在 DI 容器中添加所有 IRepository 处理程序。要从 DI 注册中排除某些特殊类,有一种使用反射的方法,
Type[] handlers = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && t.Name != "SpecialClass" && t.GetInterfaces().
Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRepository<>))).ToArray();
foreach (Type concreteHandler in handlers)
Type? handlerInterface = concreteHandler.GetInterfaces().First(i => i.GetGenericTypeDefinition() == typeof(IRepository<>));
services.AddScoped(handlerInterface, concreteHandler);
这里,handlers 数组将保存 IRepository 的所有具体实现,不包括 Specialclass,使用 foreach 您可以在 DI 中添加所有具有具体实现的对象。
【讨论】:
以上是关于C#依赖注入相同Generic Type的多个实现的主要内容,如果未能解决你的问题,请参考以下文章