将服务或回购单元中的工作单元分离

我试图将我的工作单元与我的服务或存储库分离,以便每当我想添加新服务时,我都不必触摸UoW代码。 我该怎么做呢?

_categoryService = _unitOfWork.Get(); 

而不是

 _unitOfWork.CategoryService.Add(category) 

我可以说;

 _categoryService.Add(category); 

我试图将我的工作单元与我的服务或存储库分离,以便每当我想添加新服务时都不必触及UoW代码

嗯,这是一个好的开始! 😉

我提出的解决方案不是唯一可行的解​​决方案,有几种很好的方法可以实现UoW(Google会帮助你)。 但这应该会给你一个大局。

首先,创建2个接口:IUnitOfWork和IRepository

 public interface IUnitOfWork : System.IDisposable { IRepository GetRepository() where TEntity : class; void Save(); } public interface IRepository : IDisposable where T : class { void Add(T entity); void Delete(T entity); void Update(T entity); T GetById(long Id); IEnumerable All(); IEnumerable AllReadOnly(); IEnumerable Find(Expression> predicate); } 

实现非常简单(为了便于阅读,我删除了所有注释,但不要忘记添加你的;-))

 public class UnitOfWork : IUnitOfWork where TContext : IDbContext, new() { private readonly IDbContext _ctx; private Dictionary _repositories; private bool _disposed; public UnitOfWork() { _ctx = new TContext(); _repositories = new Dictionary(); _disposed = false; } public IRepository GetRepository() where TEntity : class { if (_repositories.Keys.Contains(typeof(TEntity))) return _repositories[typeof(TEntity)] as IRepository; var repository = new Repository(_ctx); _repositories.Add(typeof(TEntity), repository); return repository; } public void Save() { try { _ctx.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { ex.Entries.First().Reload(); } } … } public class Repository : IRepository where T : class { private readonly IDbContext _context; private readonly IDbSet _dbset; public Repository(IDbContext context) { _context = context; _dbset = context.Set(); } public virtual void Add(T entity) { _dbset.Add(entity); } public virtual void Delete(T entity) { var entry = _context.Entry(entity); entry.State = EntityState.Deleted; } public virtual void Update(T entity) { var entry = _context.Entry(entity); _dbset.Attach(entity); entry.State = EntityState.Modified; } public virtual T GetById(long id) { return _dbset.Find(id); } public virtual IEnumerable All() { return _dbset.ToList(); } public virtual IEnumerable AllReadOnly() { return _dbset.AsNoTracking().ToList(); } public IEnumerable Find(Expression> predicate) { return _dbset.Where(predicate); } } 

如您所见,两个实现都使用IDbContext接口。 此界面仅用于简单测试目的:

 public interface IDbContext { DbSet Set() where T : class; DbEntityEntry Entry(T entity) where T : class; int SaveChanges(); void Dispose(); } 

(如您所见,我正在使用EntityFramework Code First)

现在已经设置了整个管道,让我们看一下如何在服务中使用它。 我有一个基本服务,看起来像这样:

 internal class Service where T : class { internal Service(Infrastructure.IUnitOfWork uow) { _repository = uow.GetRepository(); } protected Infrastructure.IRepository Repository { get { return _repository; } } private readonly Infrastructure.IRepository _repository; } 

我的所有服务都inheritance自这个基本服务。

 internal class CustomerService : Service { internal CustomerService(Infrastructure.IUnitOfWork uow) : base(uow) { } internal void Add(Model.Customer customer) { Repository.Add(customer); } internal Model.Customer GetByID(int id) { return Repository.Find(c => c.CustomerId == id); } } 

就是这样!

现在,如果你想在一个Facade方法或其他地方共享同一个UoW到几个服务,它可能看起来像这样:

 using (var uow = new UnitOfWork()) { var catService = new Services.CategoryService(uow); var custService = new Services.CustomerService(uow); var cat = new Model.Category { Name = catName }; catService.Add(dep); custService.Add(new Model.Customer { Name = custName, Category = cat }); uow.Save(); } 

希望这可以帮助!