我目前正在努力实施IUnitOfwork。 我们假设我有一个有两种方法的接口:
public interface IRepository<TEntity, in TKey>
{
TEntity Get(TKey id);
IQueryable<TEntity> All();
}
现在,假设我有几个实现此接口的类(实体)。 但是,某些实体可能需要使用其他方法进行查询,例如GetById(int id)。
这可以通过创建一个名为IRepositoryWithGetById
的新接口轻松解决。public interface IRepository<TEntity, in TKey>
{
TEntity Get(TKey id);
TEntity GetById(int id);
IQueryable<TEntity> All();
}
这将是导致维护代码的噩梦。 我正在考虑使用装饰器模式,但我找不到一个好的解决方案。
注意:我正在使用接口,因为我应该可以模拟它。
正如用户所建议的那样,我正在使用接口继承,所以这里是更新后的代码:
public class Wrapper
{
public IRepository standardRepository = new Repository();
public IDeleteRepository deleteRepository = new DeleteRepository();
public ICreateRepository createRepository = new CreateRepository();
}
public class Repository : IRepository
{
public void GetAll() { }
public void GetById(int id) { }
}
public class DeleteRepository : Repository, IDeleteRepository
{
public void Delete() { }
}
public class CreateRepository : Repository, ICreateRepository
{
public void Create() { }
}
public interface IRepository
{
void GetAll();
void GetById(int id);
}
public interface IDeleteRepository : IRepository
{
void Delete();
}
public interface ICreateRepository : IRepository
{
void Create();
}
任何知道我如何解决这个问题的人?
答案 0 :(得分:0)
我认为KrishnaDhungana建议的解决方案运行正常。这是一个我理解的例子,以简单的班级学生为例。构建存储库很容易,并测试是否注入了实现方法......
public class Student
{
int NoOfParties;
int NoOfHangOvers;
}
public interface IRepo<T>
{
IEnumerable<T> GetAll();
T GetByID();
}
public interface IRepoCreate<T>
{
Int32 Create();
}
public interface IRepoDelete<T>
{
void Delete();
}
public interface IStudentRepo : IRepo<Student>, IRepoCreate<Student>, IRepoDelete<Student>
{
IEnumerable<Student> GetAll();
Student GetByID();
int Create();
void Delete();
Student GetByParty();
}
public class MSSQLStudentRepo : IStudentRepo
{
public IEnumerable<Student> GetAll() { \\stuff }
public Student GetByID() { \\stuff }
public int Create() { \\stuff }
public void Delete() { \\stuff }
public Student GetByParty() { \\stuff }
}
public class MySQLStudentRepo : IStudentRepo
{
public IEnumerable<Student> GetAll() { \\stuff }
public Student GetByID() { \\stuff }
public int Create() { \\stuff }
public void Delete() { \\stuff }
public Student GetByParty() { \\stuff }
}
public void ImplementationExample()
{
IStudentRepo Repo = new MSSQLStudentRepo();
var Bob = Repo.GetByParty();
}
答案 1 :(得分:0)
在装饰器模式中,可能没有其他方法。装饰器模式意味着方法将保持相同但行为可能会更改。我正在写一篇关于它的博客,我会在完成后更新这个回复。
以下代码可能会对您有所帮助,因为所有函数都可以轻松放入sigle类中,您可以将它强制转换为相应的返回代码。
using System.Linq;
public interface IRepository<TEntity, in TKey>
{
TEntity Get(TKey id);
IQueryable<TEntity> All();
}
public interface IRepository
{
void GetAll();
void GetById(int id);
}
public interface IDeleteRepository : IRepository
{
void Delete();
}
public interface ICreateRepository : IRepository
{
void Create();
}
public class Wrapper
{
private readonly CombinedRepository standardRepository = new CombinedRepository();
public IRepository Repository
{
get { return standardRepository; }
}
public ICreateRepository CreateRepository
{
get { return standardRepository; }
}
public IDeleteRepository DeleteRepository
{
get { return standardRepository; }
}
}
public class CombinedRepository : IRepository, IDeleteRepository, ICreateRepository
{
public void GetAll()
{
}
public void GetById(int id)
{
}
public void Delete()
{
}
public void Create()
{
}
}
答案 2 :(得分:0)
我认为abstract
类适用于需要模拟的存储库,virtual
实现可以根据需要覆盖。
public interface IRepository<TEntity, in TKey>
{
TEntity Get(TKey id);
TEntity GetById(int id);
IQueryable<TEntity> All();
}
public abstract class Repository : IRepository
{
public virtual TEntity Get(TKey id) { throw new NotImplementedException(); }
public virtual TEntity GetById(int id) { throw new NotImplementedException(); }
public virtual IQueryable<TEntity> All() { throw new NotImplementedException(); }
}
public class FullRepo : Repository
{
public virtual TEntity Get(TKey id) { /*Implement it!*/ }
public virtual TEntity GetById(int id) { /*Implement it!*/ }
public virtual IQueryable<TEntity> All() { /*Implement it!*/ }
}
// No GetById here
public class PartialRepo : Repository
{
public virtual TEntity Get(TKey id) { /*Implement it!*/ }
public virtual TEntity GetById(int id) { throw new NotSupportedException(); }
public virtual IQueryable<TEntity> All() { /*Implement it!*/ }
}
基本上,只实现你需要的东西,接口/抽象类暴露一切。这种方法(至少对我而言)非常易读且易于扩展......并且非常可模仿。
为了避免投掷而不允许使用这些方法,您可以使用ObsoleteAttribute
(MSDN Reference)
// No GetById here
public class PartialRepo : Repository
{
public virtual TEntity Get(TKey id) { /*Implement it!*/ }
[Obsolete("This method can't be used by this repository", true)]
public virtual TEntity GetById(int id) { /*Can be empty*/ }
public virtual IQueryable<TEntity> All() { /*Implement it!*/ }
}
传递true
会使方法的调用成为编译错误(VS会说它已过时&#34;所以它不会完全正确,但它不会尽管如此,仍然可以调用该方法。