美好的一天, 我想使用来自this example的UnitOfWork(实体框架) - 存储库 - 应用服务层。 应用服务示例:
public class CustomerService : ICustomerService
{
readonly ICustomerRepository _customerRepository;
readonly IUnitOfWorkFactory _unitOfWorkFactory;
public CustomerService(IUnitOfWorkFactory unitOfWorkFactory, ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
_unitOfWorkFactory = unitOfWorkFactory;
}
public void CreateCustomer(CreateCustomerRequest request)
{
using (var unitOfWork = _unitOfWorkFactory.Create())
{
try
{
customer = new Customer { FirstName = request.FirstName, LastName = request.LastName };
_customerRepository.Add(customer);
unitOfWork.Commit();
}
catch (Exception ex)
{
unitOfWork.Rollback();
}
}
}
}
如何将unitOfWork Context与Repository交互?我如何在存储库(_customerRepository)中共享当前上下文(通过使用UnitOfWork工厂)?交易怎么样?
作为DI容器,它使用AutoFac。
提前致谢!
答案 0 :(得分:1)
如果你想同时使用我建议你做这样的事情
public interface IUnitOfWork
{
void Commit();
IDbSet<T> Set<T>() where T : class;
}
现在你的DBContext实现它:
public class MyDBContext : DbContext, IUnitOfWork
{
public void Commit()
{
SaveChanges();
}
public int SaveChanges()
{
//see below
SetIsolationLevel();
base.SaveChanges();
}
}
对于存储库,您只需要传递DBContext
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : EntityBase
{
protected DbContext Context;
//this is the constructor for your base repositories
public Repository(DbContext context)
{
if (context == null)
{
throw new ArgumentNullException();
}
Context = context;
}
public void Save(TEntity entity)
{
Save(entity);
}
public void Save(TEntity entity)
{
if (entity == null) return;
if (entity.Id == 0)
{
Add(entity);
}
else
{
//state is modified
Context.Entry(entity).State = EntityState.Modified;
Context.Set<TEntity>().Attach(entity);
}
}
但是,您的DI应该只保存对每种类型的引用,以便在您需要时解决它们,您有责任知道您注入的类型和参数。
现在对于您的交易,根据您要指定的隔离级别,您可以执行类似这样的操作
public MyDBContext (string connectionName)
: base(connectionName)
{
Configuration.AutoDetectChangesEnabled = false;
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
Database.CommandTimeout = 300;
Database.Log = sql => Debug.WriteLine(sql);
SetIsolationLevel("READ UNCOMMITTED");
}
private void SetIsolationLevel(string isolationLevel = null)
{
if (isolationLevel == null)
isolationLevel = TransactionUtils.IsolationLevelString;
if (!string.IsNullOrEmpty(isolationLevel))
{
Database.ExecuteSqlCommand($"SET TRANSACTION ISOLATION LEVEL {isolationLevel};");
}
}
无论如何,我强烈建议您阅读这篇文章,以便在想要使用您的工作单元和存储库时有另一种观点
http://rob.conery.io/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/