我正在尝试为数据访问层创建一个Repository&UnitOfWork。在我当前的实现中,我每次创建新的存储库时都必须修改我的UnitOfWork。我想避免这种情况,并保留扩展我的存储库抽象类的功能。
以下是我的通用Repository和UnitOfWork接口和类
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类。
在网上搜索时我发现了以下内容,但在我的情况下它不起作用,因为我的RepositoryBase是一个抽象类。
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
类来返回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();
}
使用工作单元的唯一目的是能够在几个不同的存储库之间共享相同的上下文。在你的Dictionary<Type, object>
中暴露UnitOfWork
将无法解决任何问题,因为使用泛型的目的是提供编译时类型的安全性。