我目前有一个 Repository/UnitOfWork 模式。但是,我无法弄清楚如何摆脱这种硬耦合。
这是我的模式的概述:
业务逻辑层
- 存储库
- 用作类型约束
- IRepository< TModel, TDTO >
- 实现 IRepository
- 一般 CRUD 方法
- IEmployeeRepository<TModel>
- 实现 IRepository< TModel, EmployeeDTO >
- 一些员工特定的方法
- 工作单位
- 存储库的吸气剂
- 保存方法
- IEntityWithId
- 强制(和公开)DTO 和 EF POCO 具有称为 ID 的 Int32 字段的接口
- 用作类型约束
- EmployeeDTO(在实现的 EmployeeRepository 中使用 AutoMapper 映射)
- 核心项目和(即将到来的)测试项目中使用的 DTO 实体
数据层(用 Ninject 注入)
- 工作单位
- 基于Entity Framework的IUnitOfWork实现
- 员工资料库
- IEmployeeRepository<TModel>的实现
- 员工
- 英孚波科
核
- 员工控制器
- 参数化构造器EmployeesController(IUnitOfWork unitOfWork)
- IUnitOfWork 被注入一个 Ninject 模块作为一个 UnitOfWork(来自数据层)
这些是我的通用 IRepository 接口中的问题方法。
TDTO Find(Expression<Func<TModel, bool>> filter);
和
IEnumerable<TDTO> FindAll(Expression<Func<TModel, bool>> filter);
如您所见,其中有 TModel,用于构建表达式以过滤结果。我可以做一些事情,比如在 DTO 上使用表达式,但这需要映射到 DTO 的员工的完整列表(也就是它不会生成 SQL 过滤器,但它会过滤 SELECT * FROM Employee 结果列表)。所以这不是一个好的选择。
另一种更可行但不是最佳的解决方案是使用动态 LINQ。这样,我可以在 Find / FindAll 方法中传递一个简单的字符串并摆脱 TModel 要求。然而,这意味着重构变得烦人,因为它用魔术字符串填充代码。