gpt4 book ai didi

c# - 将工作单元与服务或 repo 分离

转载 作者:太空狗 更新时间:2023-10-29 20:54:52 24 4
gpt4 key购买 nike

我正在尝试将我的工作单元与我的服务或存储库分离,这样每当我想添加新服务时就不必触及 UoW 代码。我该怎么做?

_categoryService = _unitOfWork.Get<ICategoryService>();

所以代替

_unitOfWork.CategoryService.Add(category)

我只能说;

_categoryService.Add(category);

最佳答案

I am trying to decouple my unit of work from my services or repository so that I won’t have to touch the UoW code whenever I wish to add a new service

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

我提出的解决方案不是唯一可能的解决方案,有几种实现 UoW 的好方法(Google 会帮助您)。但这应该让您了解全局。

首先,创建2个接口(interface):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 接口(interface)。此接口(interface)只是为了方便测试:

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

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

现在整个管道都已设置好,让我们看看如何在服务中使用它。我有一个如下所示的基本服务:

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();
}

希望这对您有所帮助!

关于c# - 将工作单元与服务或 repo 分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15181290/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com