Fix*_*xer 7 c# asp.net-mvc repository-pattern
我已经设置了我的通用存储库,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
为了在我的MVC应用程序中启用依赖项注入,我还创建了一个Product接口,因为签名不同.其他存储库也是如此.
public interface IProductRepository : IRepository<Product>
{
IEnumerable<Product> GetDiscountedProducts();
}
Run Code Online (Sandbox Code Playgroud)
和实现(注意继承)
public class ProductRepository : Repository<Product>, IProductRepository
{
public IEnumerable<Product> GetDiscountedProducts()
{
return _context.Set<Product>().Where(x=>x)...
}
}
Run Code Online (Sandbox Code Playgroud)
最后,使用unity将存储库注入MVC控制器
public HomeController(IProductRepository repository)
{
}
Run Code Online (Sandbox Code Playgroud)
这只是我还是这个继承链在这里有点乱?有没有办法改进这个设计?
我建议避免IProductRepository这种特殊情况(当简单地添加单个和非常具体的方法时)并增强原始IRepository接口,如下所示:
public interface IRepository<TEntity> : IDisposable
where TEntity : Entity
{
TEntity GetById(int id);
IEnumerable<TEntity> List(IFilterCriteria criteria);
}
Run Code Online (Sandbox Code Playgroud)
然后实施
public sealed class ProductDiscountFilterCriteria : IFilterCriteria
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,您需要定义一些逻辑来将条件转换为查询,它可能是一个LINQ表达式,因为您已经在使用LINQ.如果这种creteria表达方法对你的情况来说很复杂 - 我建议坚持你提出的方法.
编辑: IFilterCriteria简单的查询对象模式实现
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)
}
}
Run Code Online (Sandbox Code Playgroud)
OR原始SQL条件构建器:
public sealed class ProductDiscountFilterCriteria : IFilterCriteria<string>
{
public decimal Discount { get; private set; }
public string ToQuery()
{
// simplified
return "WHERE Discount < " + this.Discount;
}
}
Run Code Online (Sandbox Code Playgroud)
那么你就可以像以下一样使用它:
var products = productRepository.List<Product>(
new DiscountFilterCriteria { Discount = 50 });
Run Code Online (Sandbox Code Playgroud)
动态LINQ示例和文章:
| 归档时间: |
|
| 查看次数: |
2369 次 |
| 最近记录: |