我正在尝试编写一个通用的NTier API库,我可以在我的所有"模块中使用#34; (如UserModule,AccountingModule等),目前使用EF,但数据访问层不应与EF硬连接。问题是,我似乎无法找到一种良好的方式来合并DbContext。
我计划的结构是将通用NTier库作为独立项目,然后在我的Module项目中引用它,其中只是类库和为特定主题区域编写的NTier API。
举个例子,这是我的通用EntityRepository的片段:
public class EntityRepository<TClass> : IEntityRepository<TClass> where TClass : Entity, new()
{
private DbContext Context => //Not sure what to do here.
public void Delete<TTableClass>(Guid id) where TTableClass : Entity, new ()
{
TTableClass record = Context.Set<TTableClass>().Find(id);
Context.Set<TTableClass>().Remove(record);
Context.SaveChanges();
}
注意,TClass与TTableClass不同。现在在我之前的这个API迭代中,在我决定将内容分成模块之前,它看起来像这样:
public class EntityRepository<TClass, TTableClass> : IEntityRepository<TClass> where TClass : Entity, new()
where TTableClass : Entity, new ()
{
private DbContext Context => EntityDbContextFactory<MyDbContext>.GetInstance();
protected DbSet<TTableClass> DbSet => Context.Set<TTableClass>();
public void Delete(Guid id)
{
TTableClass record = DbSet.Find(id);
DbSet.Remove(record);
Context.SaveChanges();
}
但这只是因为它只是一个上下文所以我知道上下文类将是什么,现在我不知道。显而易见的答案是将上下文类作为通用参数包含在内,但这是一个糟糕的设计,因为这意味着我的服务类必须知道我的存储库层查询数据的方式,漏洞抽象不好。事实上,我之前已经完成了我的通用API之前的2个版本,它看起来像这样:
public abstract class EntityRepository<TClass, TDbContext>
where TClass : Entity, new ()
where TDbContext : DbContext, new()
{
private DbContext Context
{
get { return EntityContextFactory<TDbContext>.Current(); }
}
但这使得我的EntityService和具体的实现定义如下所示:
public abstract class EntityService<TRepositoryClass, TClass, TDbContext>
where TClass : Entity, new()
where TDbContext : DbContext, new()
where TRepositoryClass : EntityRepository<TClass, TDbContext>
public class UserService : EntityService<UserRepository, User, MyDbContext>
哎呀,抽象漏洞太多了。另一个问题是我不能将DbContext类存储为类的成员/属性(因此上面是静态工厂引用),因为我无法保证使用我的库的其他程序员正在使用DI容器< / p>
简而言之,如果符合以下条件,如何使通用API工作: