通用工作单元
Generic UnitOfWork
我正在尝试为数据访问层创建存储库和工作单元。在我当前的实现中,每次创建新存储库时我都必须修改我的 UnitOfWork。我想避免这种情况并保留扩展我的存储库摘要的功能 class.
以下是我的通用存储库和 UnitOfWork 接口 & classes
public interface IRepositoryBase<T> where T : class
{
IList<T> FindAll();
T FindByCondition(Expression<Func<T, bool>> expression);
void Create(T entity);
void Update(T entity);
void Delete(T entity);
}
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected DBContext _dbContext { get; set; }
public RepositoryBase(DBContext dbContext)
{
_dbContext = dbContext;
}
//other methods removed
public void Create(T entity)
{
_dbContext.Set<T>().Add(entity);
}
}
public interface IUnitOfWork
{
IReminderRepository Reminder { get; }
void Save();
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
protected DBContext _dbContext { get; set; }
private IReminderRepository _reminderRepository;
public UnitOfWork(DBContext dbContext)
{
_dbContext = dbContext;
}
public IReminderRepository Reminder
{
get
{
return _reminderRepository = _reminderRepository ?? new ReminderRepository(_dbContext);
}
}
public void Save()
{
_dbContext.SaveChanges();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
在这里,我可以通过将特定的存储库实现为
来根据我的特定需求扩展我的存储库
public interface IReminderRepository : IRepositoryBase<Reminder>
{
IList<Reminder> GetAllReminders();
Reminder GetReminderById(Guid id);
Reminder GetReminderByName(string name);
void CreateReminder(Reminder reminder);
void UpdateReminder(Reminder reminder);
void DeleteReminder(Reminder reminder);
}
public class ReminderRepository : RepositoryBase<Reminder>, IReminderRepository
{
public ReminderRepository(DBContext dbContext)
: base(dbContext)
{
_dbContext = dbContext;
}
//other methods removed
public Reminder GetReminderByName(string name)
{
return FindAll()
.OrderByDescending(r => r.Name)
.FirstOrDefault(r => r.Name == name);
//return FindByCondition(r => r.Name == name);
}
}
这没关系,但是每当我创建一个新的特定存储库时,我都必须修改 UnitOfWork class 以及为新存储库添加一个新的 属性。
在网上搜索时,我发现了以下内容,但它在我的情况下不起作用,因为我的 RepositoryBase 是一个抽象 class。
public interface IUnitOfWork
{
void Save();
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DBContext _dbContext { get; set; }
private readonly Dictionary<Type, object> _repositories = new Dictionary<Type, object>();
public Dictionary<Type, object> Repositories
{
get { return _repositories; }
set { Repositories = value; }
}
public UnitOfWork(DBContext dbContext)
{
_dbContext = dbContext;
}
public IRepositoryBase<T> Repository<T>() where T : class
{
if (Repositories.Keys.Contains(typeof(T)))
{
return Repositories[typeof(T)] as IRepositoryBase<T>;
}
IRepositoryBase<T> repo = new RepositoryBase<T>(_dbContext);//This does not work
Repositories.Add(typeof(T), repo);
return repo;
}
public void Save()
{
_dbContext.SaveChanges();
}
}
您显然需要在代码中的某处获得对 IReminderRepository
的引用,以便能够使用剩余的特定 API。
如果您不想将 UnitOfWork
class 扩展为 return 和 IReminderRepository
,您可以在实际使用特定的方法中自己创建一个存储库,例如:
using (var context = new DBContext())
{
IUnitOfWork uow = new UnitOfWork(context);
ReminderRepository repository = new ReminderRepository(context);
Reminder remainder = repository.GetReminderByName("...");
remainder.SomeProperty = "updated value..";
uow.Save();
}
使用工作单元的唯一目的是无论如何都能够在几个不同的存储库之间共享相同的上下文。在 UnitOfWork
中公开 Dictionary<Type, object>
不会解决任何问题,因为使用泛型的目的是提供编译时类型安全。
我正在尝试为数据访问层创建存储库和工作单元。在我当前的实现中,每次创建新存储库时我都必须修改我的 UnitOfWork。我想避免这种情况并保留扩展我的存储库摘要的功能 class.
以下是我的通用存储库和 UnitOfWork 接口 & classes
public interface IRepositoryBase<T> where T : class
{
IList<T> FindAll();
T FindByCondition(Expression<Func<T, bool>> expression);
void Create(T entity);
void Update(T entity);
void Delete(T entity);
}
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected DBContext _dbContext { get; set; }
public RepositoryBase(DBContext dbContext)
{
_dbContext = dbContext;
}
//other methods removed
public void Create(T entity)
{
_dbContext.Set<T>().Add(entity);
}
}
public interface IUnitOfWork
{
IReminderRepository Reminder { get; }
void Save();
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
protected DBContext _dbContext { get; set; }
private IReminderRepository _reminderRepository;
public UnitOfWork(DBContext dbContext)
{
_dbContext = dbContext;
}
public IReminderRepository Reminder
{
get
{
return _reminderRepository = _reminderRepository ?? new ReminderRepository(_dbContext);
}
}
public void Save()
{
_dbContext.SaveChanges();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
在这里,我可以通过将特定的存储库实现为
来根据我的特定需求扩展我的存储库public interface IReminderRepository : IRepositoryBase<Reminder>
{
IList<Reminder> GetAllReminders();
Reminder GetReminderById(Guid id);
Reminder GetReminderByName(string name);
void CreateReminder(Reminder reminder);
void UpdateReminder(Reminder reminder);
void DeleteReminder(Reminder reminder);
}
public class ReminderRepository : RepositoryBase<Reminder>, IReminderRepository
{
public ReminderRepository(DBContext dbContext)
: base(dbContext)
{
_dbContext = dbContext;
}
//other methods removed
public Reminder GetReminderByName(string name)
{
return FindAll()
.OrderByDescending(r => r.Name)
.FirstOrDefault(r => r.Name == name);
//return FindByCondition(r => r.Name == name);
}
}
这没关系,但是每当我创建一个新的特定存储库时,我都必须修改 UnitOfWork class 以及为新存储库添加一个新的 属性。
在网上搜索时,我发现了以下内容,但它在我的情况下不起作用,因为我的 RepositoryBase 是一个抽象 class。
public interface IUnitOfWork
{
void Save();
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DBContext _dbContext { get; set; }
private readonly Dictionary<Type, object> _repositories = new Dictionary<Type, object>();
public Dictionary<Type, object> Repositories
{
get { return _repositories; }
set { Repositories = value; }
}
public UnitOfWork(DBContext dbContext)
{
_dbContext = dbContext;
}
public IRepositoryBase<T> Repository<T>() where T : class
{
if (Repositories.Keys.Contains(typeof(T)))
{
return Repositories[typeof(T)] as IRepositoryBase<T>;
}
IRepositoryBase<T> repo = new RepositoryBase<T>(_dbContext);//This does not work
Repositories.Add(typeof(T), repo);
return repo;
}
public void Save()
{
_dbContext.SaveChanges();
}
}
您显然需要在代码中的某处获得对 IReminderRepository
的引用,以便能够使用剩余的特定 API。
如果您不想将 UnitOfWork
class 扩展为 return 和 IReminderRepository
,您可以在实际使用特定的方法中自己创建一个存储库,例如:
using (var context = new DBContext())
{
IUnitOfWork uow = new UnitOfWork(context);
ReminderRepository repository = new ReminderRepository(context);
Reminder remainder = repository.GetReminderByName("...");
remainder.SomeProperty = "updated value..";
uow.Save();
}
使用工作单元的唯一目的是无论如何都能够在几个不同的存储库之间共享相同的上下文。在 UnitOfWork
中公开 Dictionary<Type, object>
不会解决任何问题,因为使用泛型的目的是提供编译时类型安全。