问题描述
Registering repository using generics with multiple types <T, T> c# dotnet core
我正在创建一个通用存储库,如下所示:
public interface IRepository<T> where T : class
{
Task<T> GetById(int id);
Task Add(T entity);
void AddRange(IEnumerable<T> entities);
Task<int> Save();
Task Delete(int id);
void Delete(T entity);
T Update(T entity);
}
public abstract class Repository<T, TContext> : IRepository<T> where T :
class where TContext : DbContext
{
protected readonly TContext _context;
private DbSet<T> _table;
protected Repository(TContext context)
{
_context = context;
_table = _context.Set<T>();
}
// implementation
}
我想将任何 DBcontext 传递给实现,具体的实现应该是这样的:
public interface ICouponRepository : IRepository<Coupon>
{
Task RedeemCoupon(int id, Guid userId);
}
public class CouponRepository : Repository<Coupon, CouponApiDBContext>, ICouponRepository
{
private readonly CouponApiDBContext _couponApiDBContext;
protected CouponRepository(CouponApiDBContext couponApiDBContext) : base(couponApiDBContext)
{
_couponApiDBContext = couponApiDBContext;
}
public Task RedeemCoupon(int id, Guid userId)
{
throw new NotImplementedException();
}
}
然后我按如下方式注册这两项服务:
services.AddTransient(typeof(IRepository<>), typeof(Repository<,>))
.AddTransient<ICouponRepository, CouponRepository>()
但是我可以实例化通用存储库,但出现以下错误:
An unhandled exception of type 'System.ArgumentException' occurred in xxx.dll: 'Cannot instantiate implementation type 'xxx.Repositories.Repository2[T,TContext]' for service type 'xxx.Repositories.IRepository1[T]'.'
答案
立即想到三件事。
第一个与您的问题无关,但 CouponRepository 不应该有自己的 _couponApiDBContext 成员,它可以访问基类 TContext - 这就是首先让它通用的全部意义。
第二个是您在 ICouponRepository 中使用 RedeemCoupon 方法专门化了 IRepository<Coupon> - 因此您注册开放泛型类型的机会为零,只是期望 DI 知道您所追求的实际接口。
您只剩下删除此 AddTransient(typeof(IRepository<>), typeof(Repository<,>)) - 这是毫无意义的,因为 DI 无论如何都无法实例化抽象类,这是错误消息的根本原因,您应该注册 AddTransient<ICouponRepository, CouponRepository>() 并在您需要的地方请求 ICouponRepository - 您不能请求 IRepository<Coupon> 因为它没有我认为您需要的 RedeemCoupon 方法。

文章讨论了在C#.NETCore应用中创建泛型仓储接口和实现时遇到的问题。作者指出,尝试注册泛型仓储服务时出现错误,原因是无法实例化抽象类。解决方案是删除对抽象仓储的无效注册,而应专注于注册具体实现如`ICouponRepository`和`CouponRepository`。此外,作者还建议`CouponRepository`不应有独立的数据库上下文成员,应利用基类的上下文来保持代码的简洁性和通用性。
86

被折叠的 条评论
为什么被折叠?



