如何在服务和存储库之间注入相同的dbcontext实例
本文关键字:注入 实例 dbcontext 之间 服务 存储 | 更新日期: 2023-09-27 18:10:33
嗨,我正在做一个项目,目前我正在用实体框架构建数据层
Dbcontext
public interface IDatabaseContext : IDisposable
{
IDbSet<TestEntity> TestEntitys { get; }
int SaveChanges();
}
public class DatabaseContext : DbContext, IDatabaseContext
{
static DatabaseContext()
{
System.Data.Entity.Database.SetInitializer<DatabaseContext>(null);
}
public DatabaseContext(string connectionString) :
base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TestEntityConfiguration());
base.OnModelCreating(modelBuilder);
}
public IDbSet<TestEntity> TestEntitys
{
get;
set;
}
public override int SaveChanges()
{
return base.SaveChanges();
}
}
工作单元:
public interface IUnitOfWork : IDisposable
{
int Commit();
IDatabaseContext Context { get; }
}
public sealed class UnitOfWork : IUnitOfWork, IDisposable
{
private IDatabaseContext _dbContext;
private bool disposed = false;
public UnitOfWork(IDatabaseContext mydbContext)
{
//var builder=DataBaseConnectionStringBuilder();
//var factory = new DataBaseConnectionFactory(builder);
_dbContext = mydbContext;
}
public int Commit()
{
return _dbContext.SaveChanges();
}
public IDatabaseContext Context
{
get { return _dbContext; }
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (_dbContext != null)
{
_dbContext.Dispose();
_dbContext = null;
}
}
}
disposed = true;
}
}
服务:
public class Baseservice()
{
protacted IUnitOfWork unitofwork;
public BaseService(IUnitOfWork uow)
{
unitofwork= uow;
}
}
public class TestEntityservice() : BaseService
{
private ITestEntityReopsitory _testEntityReopsitory;
public TestEntityservice(IUnitOfWork uow,ITestEntityReopsitory testEntityReopsitory):base(uow)
{
_testEntityReopsitory=testEntityReopsitory;
}
public int AddNewData(somedto dto){
var result=_testEntityReopsitory.AddTEst(dto);
return unitofwork.Commit();
}
}
存储库:
public BaseRepository(IDatabaseContext context)
{
_dbContext = context;
}
public class TestEntityReopsitory() : BaseRepository, ITestEntityReopsitory
{
public TestEntityReopsitory(IDatabaseContext context) :base(context) {
}
public int AddTEst(somedto dto){
var entity = new TestEntity()
{
a= dto.a,
b= dto.b
}
context.Add(entity);
}
}
我关心的是,因为我在存储库中注入了我的数据库上下文(DatabaseContext),所以当存储库将解决它时,它将在存储库中有一个单独的实例 dbcontext,然后服务。因此,这意味着我将一个实体添加到一个单独的上下文,并使用不同的上下文保存。
我怎样才能确保我在存储库和服务中使用相同的实例,并且仍然保持相同的实现。
像工作单元和存储库这样的模式有很多实现的方法。例如,您可以实现只读存储库,它返回具有方法Update
和Delete
的活动记录。或者您可以实现返回普通旧对象的存储库,因此具有Update
和Delete
方法。最后,您可以实现返回普通旧对象的只读存储库,因此方法Update
和Delete
应该在工作单元中声明。
如何组织存储库和工作单元之间的交互?这可以通过组合模式注册表和工作单元:
来实现。public interface IUnitOfWork
{
IUserRepository UserRepository { get; }
IDataRepository DataRepository { get; }
void Commit();
}
或者您可以使用工作单元作为服务定位符:
public interface IUnitOfWork
{
TRepository GetRepository<TRepository>() where TRepository: IRepository;
void Commit();
}
或者您可以显式地为工作单元指定读写存储库:
public interface IUnitOfWork
{
void Join(IRepository repository);
void Commit();
}
在最后一种情况下,您可以使用带有工作单元的存储库,也可以不使用它们。在所有这些情况下,您都可以在存储库和工作单元之间共享相同的DbContext
。
在你的UnitOfWork类中,不是创建一个工厂,然后用它来创建一个IDatabaseContext对象,而是使用构造函数注入来注入一个DatabaseContext。这样的:
public UnitOfWork(IDatabaseContext db_context)
{
_dbContext = db_context;
}
对Baseservice(以及TestEntityservice)也做同样的事情,它们应该在它们的构造函数中注入IUnitOfWork,它们不应该自己创建UnitOfWork。这就是依赖注入的意义所在。
确保使用构造函数注入后,现在可以在组合根中组合整个对象图。当你这样做的时候,确保你为你的UnitOfWork和你的服务使用了相同的DatabaseContext实例。纯DI是实现这种组合的一种非常好的方式。
下面是如何使用Pure DI: var connection_string = "some connection string";
using (IDatabaseContext context = new DatabaseContext(connection_string))
{
IUnitOfWork unit_of_work = new UnitOfWork(context);
ITestEntityReopsitory reopsitory = new TestEntityReopsitory(context);
ITestEntityservice service = new TestEntityservice(unit_of_work, reopsitory);
//Consume service here
....
}
这样做的一种方法是跨存储库实例共享工作单元,这将允许您创建如下代码
using (IUnitOfWork unitOfWork = _UnitOfWorkFactory.CreateInstance()) {
var repository = _RepositoryFactory.CreateRepository<YourType>(unitOfWork);
var repositoryTwo = _RepositoryFactory.CreateRepository<YourOtherType>(unitOfWork);
unitOfWork.Commit();
}
仓库工厂
BaseRepository IRepositoryFactory.CreateRepository<T>(IUnitOfWork unitOfWork) {
//Create Instance Here
}