我已经设置了我的通用存储库,如下所示:
public interface IRepository<T> : IDisposable where T : Entity { T GetById(int id); } public abstract class Repository<T> : IRepository<T> where T : Entity { protected readonly sqlDbContext _context = new sqlDbContext(); public T GetById(int id) { return _context.Set<T>().Find(id); } }
为了在我的MVC应用程序中启用依赖项注入,我还创建了一个Product接口,因为签名不同.其他存储库也是如此.
public interface IProductRepository : IRepository<Product> { IEnumerable<Product> GetDiscountedProducts(); }
和实现(注意继承)
public class ProductRepository : Repository<Product>,IProductRepository { public IEnumerable<Product> GetDiscountedProducts() { return _context.Set<Product>().Where(x=>x)... } }
最后,使用unity将存储库注入MVC控制器
public HomeController(IProductRepository repository) { }
它只是我还是这个继承链在这里有点乱?有没有办法改进这个设计?
解决方法
我建议为这种特殊情况避免IProductRepository(当简单地添加单个且非常具体的方法时)并增强原始IRepository接口,如下所示:
public interface IRepository<TEntity> : IDisposable where TEntity : Entity { TEntity GetById(int id); IEnumerable<TEntity> List(IFilterCriteria criteria); }
然后实施
public sealed class ProductDiscountFilterCriteria : IFilterCriteria { // ... }
但在这种情况下,您需要定义一些逻辑来将条件转换为查询,它可能是一个LINQ表达式,因为您已经在使用LINQ.如果这种creteria表达方法对于你的情况来说很复杂 – 我建议坚持你提出的方法.
编辑:IFilterCriteria只是Query Object模式实现
interface IFilterCriteria<TQuery> { TQuery ToQuery(); } public sealed class ProductDiscountFilterCriteria : IFilterCriteria<DynamicExpression> { public decimal Discount { get; private set; } public DynamicExpression ToQuery() { // build expression for LINQ clause Where("Discount" > this.Discount) } }
OR原始sql条件构建器:
public sealed class ProductDiscountFilterCriteria : IFilterCriteria<string> { public decimal Discount { get; private set; } public string ToQuery() { // simplified return "WHERE Discount < " + this.Discount; } }
那么你就可以像以下一样使用它:
var products = productRepository.List<Product>( new DiscountFilterCriteria { Discount = 50 });
动态LINQ示例和文章:
> Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
> Dynamic LINQ (A little more dynamic)
> Dynamic LINQ Part 2 (Evolution)