从服务或回购分离工作单位(Decouple unit of work from services o

2019-07-20 21:19发布

我想我的脱钩从我的服务或资料库的工作单位,这样我不会有触摸UOW代码,每当我想补充一个新的服务。 我该怎么做呢?

_categoryService = _unitOfWork.Get<ICategoryService>();

所以不是

_unitOfWork.CategoryService.Add(category)

我只能说,

_categoryService.Add(category);

Answer 1:

我想我的脱钩从我的服务或资料库的工作单位,这样我就不必触碰UOW代码,每当我想补充一个新的服务

嗯,这是一个良好的开端! ;-)

我提出的解决方案是不是唯一可能的解决方案,有落实UOW(谷歌将帮助你)几个很好的方式。 但是,这应该给你的大图片。

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

public interface IUnitOfWork : System.IDisposable
{
  IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
  void Save();
}

public interface IRepository<T> : IDisposable where T : class
{
  void Add(T entity);
  void Delete(T entity);
  void Update(T entity);
  T GetById(long Id);
  IEnumerable<T> All();
  IEnumerable<T> AllReadOnly();
  IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
} 

的实现是非常简单(我删除了我的可读性目的的所有意见,但不要忘了加你;-))

public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
  private readonly IDbContext _ctx;
  private Dictionary<Type, object> _repositories;
  private bool _disposed;

  public UnitOfWork()
  {
    _ctx            = new TContext();
    _repositories   = new Dictionary<Type, object>();
    _disposed       = false;
  }

  public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
  {
    if (_repositories.Keys.Contains(typeof(TEntity)))
      return _repositories[typeof(TEntity)] as IRepository<TEntity>;

    var repository = new Repository<TEntity>(_ctx);
    _repositories.Add(typeof(TEntity), repository);
    return repository;
  }

  public void Save()
  {
     try
     {
       _ctx.SaveChanges();
     }
     catch (DbUpdateConcurrencyException ex)
     {
       ex.Entries.First().Reload();
     }
  }

  …
}

public class Repository<T> : IRepository<T> where T : class
{
  private readonly IDbContext _context;
  private readonly IDbSet<T> _dbset;

  public Repository(IDbContext context)
  {
    _context = context;
    _dbset   = context.Set<T>();
  }

  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<T> All()
  {
    return _dbset.ToList();
  }

  public virtual IEnumerable<T> AllReadOnly()
  {
    return _dbset.AsNoTracking().ToList();
  }

  public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
  {
    return _dbset.Where(predicate);
  }

}

正如你所看到的,实现使用IDbContext接口。 这个接口仅仅是简单的测试目的:

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

(正如你所看到的,我使用的EntityFramework代码第一次)

现在,整个管道的建立,让我们来看看这怎么会在服务中使用。 我有一个基本的服务,看起来像这样:

internal class Service<T> where T : class
{
  internal Service(Infrastructure.IUnitOfWork uow)
  {
    _repository = uow.GetRepository<T>();
  }

  protected Infrastructure.IRepository<T> Repository
  {
    get { return _repository; }
  }

  private readonly Infrastructure.IRepository<T> _repository;
}

和我所有的服务,从这个基本的服务继承。

internal class CustomerService : Service<Model.Customer>
{
  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);
  }

}

就是这样!

现在,如果你想共享相同的UOW给几个服务,在外观方法或其他地方,它可能只是看起来像这样:

using (var uow = new UnitOfWork<CompanyContext>())
{
  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();
}

希望这可以帮助!



文章来源: Decouple unit of work from services or repo