如何使用将 DBcontext 对象传递给固有 GenericRepository抽象类的实体的构造函数
本文关键字:GenericRepository 抽象类 构造函数 实体 DBcontext 何使用 对象 | 更新日期: 2023-09-27 18:36:49
请帮助我,我应该如何将DBContext
对象传递给MyEntityRepsitory
类的构造函数?
例如:
public interface IRepository<T> where T: class
{
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly DbContext _dbContext;
public Repository(DbContext dbContext)
{
_dbContext = dbContext;
}
}
public interface IMyEntity : IRepository<MyEntity>
{
MyEntity GetSingle(int Id);
}
public class MyEntityRepository : Repository<MyEntity>, IMyEntity
{
public MyEntityRepository() : base(mydbContext){}
}
我是数据访问层设计模式和实现存储库模式的新手。我从未使用过结构图/工作单元模式。
我想知道,我可以通过多少种方式创建DbContext
对象以便我可以通过。
请向我解释各种方法的区别。
在上面的示例中,名为 MyEntityRepository
的类有一个构造函数,dbContext
对象传递给Repository
类构造函数。请告诉我该怎么做。
非常感谢。
Edit
根据@Trevor de Koekoek的评论,从线程和事务边界的角度来看,直接注入拥有DbContext
的包装器可能会有问题。
事后看来,注入工厂是可取的,并且像这样使用:
public ConsumingClass(IRepositoryFactory injectedRepositoryFactory)
然后(如果持有对工厂的引用)
using (var applesRepository = _injectedRepositoryFactory.CreateRepository<Apples>())
{
... do something with apples
}
或通过在类上实现IDisposable
。
这为客户端提供了一个干净的存储库,并强制客户端取得存储库实例的所有权。
原始答案
正如你所建议的,你应该配置一个 IoC 容器(如 StructureMap)来为你执行此操作 - 需要使用IRepository<T>
的类将通过构造函数或 setter 注入注入一个实例。此 IMO 是最干净的实现,因为它具有可测试性,与存储库的耦合仅通过接口,存储库和使用类都不会耦合到 IoC 容器。
例如,使用构造函数注入:
public class ConsumingClass
{
public ConsumingClass(IRepository<Apples> injectedApplesRepository)
}
IRepository
到其具体类的映射是通过 IoC 引导程序(或在配置中)完成的。为了提高可测试性,我还会将您的存储库耦合到IDbContext
,而不是DbContext
,例如
private void ConfigureIoC()
{
For<IDbContext>().Use<MyDbContext>();
For<IRepository<T>>().Use<Repository<T>>();
// ... etc
}
当你的消费类由 IoC 构建时,它将递归检测所有依赖项(IRepository<T>
,然后依次IDbContext
)并构建这些依赖项及其缺陷等。
其他替代方法是服务定位器模式(现在通常被视为反模式,因为它将类耦合到定位器)和工厂方法等模式。