如何让泛型上下文仓储类兼容ApiAuthorizationDbContext与DbContext?
解决方案:让泛型上下文类支持多数据库上下文
首先明确:ApiAuthorizationDbContext本质是继承自DbContext的子类,你当前的ContextRepository<TContext>泛型约束where TContext : DbContext已经天然支持它了,不需要修改核心约束。下面给你两种实用的实现思路:
1. 直接基于现有代码创建多上下文实例
既然ApiAuthorizationDbContext符合DbContext的约束,你可以分别针对两种上下文创建ContextRepository的实例,各自管理对应数据库的仓储:
// 针对身份授权上下文创建仓库实例 var authContext = new ApiAuthorizationDbContext(...); var authRepoManager = new ContextRepository<ApiAuthorizationDbContext>(authContext); var userRepo = authRepoManager.Repository<ApplicationUser>(); // 针对业务数据库上下文创建仓库实例 var appContext = new AppDbContext(...); var appRepoManager = new ContextRepository<AppDbContext>(appContext); var productRepo = appRepoManager.Repository<Product>();
2. 封装统一工厂类管理多上下文(推荐)
如果想通过一个入口获取不同上下文的仓储,可以封装一个工厂类,统一管理不同类型的ContextRepository实例:
public class RepositoryFactory { private readonly Dictionary<Type, object> _contextRepos = new(); // 注册上下文对应的仓库管理器 public void RegisterContext<TContext>(TContext context) where TContext : DbContext { var repoManager = new ContextRepository<TContext>(context); _contextRepos.Add(typeof(TContext), repoManager); } // 获取指定上下文的仓储 public IGenericRepository<TEntity> GetRepository<TContext, TEntity>() where TContext : DbContext where TEntity : class { if (_contextRepos.TryGetValue(typeof(TContext), out var repoManager)) { return ((ContextRepository<TContext>)repoManager).Repository<TEntity>(); } throw new InvalidOperationException($"未注册上下文类型:{typeof(TContext).Name}"); } }
使用方式:
var factory = new RepositoryFactory(); factory.RegisterContext(new ApiAuthorizationDbContext(...)); factory.RegisterContext(new AppDbContext(...)); // 获取身份授权上下文的用户仓储 var userRepo = factory.GetRepository<ApiAuthorizationDbContext, ApplicationUser>(); // 获取业务上下文的产品仓储 var productRepo = factory.GetRepository<AppDbContext, Product>();
修复你代码里的一个隐藏问题
注意你的ContextRepository<TContext>中Repositories属性的setter会导致无限递归栈溢出,因为你在setter里又赋值给了Repositories本身,应该去掉setter:
// 修正后的代码 public Dictionary<Type, object> Repositories { get { return _repositories; } // 去掉setter,因为_repositories是readonly的,外部无需修改 }
内容的提问来源于stack exchange,提问作者Jeandre Jonker
相关产品推荐
相关产品推荐

