好吧,既然您想使用 DI 框架(可能是一个不错的选择:)),您已经知道需要使用接口定义 DAL。然后,您可以使用实现这些接口的类来充当 WCF 服务或 DB 上下文的适配器。
您的设计的一个很好的方面是,您将自动将自己与 WCF 服务和数据库上下文的未来可能的替换隔离开来 - 即,每当 Microsoft 发布另一种数据访问技术时。 :) 或者更有可能的是,每当您的团队决定采用不同的方法时,例如从 WCF 服务切换到 REST 服务。
一般来说存储库模式 http://www.martinfowler.com/eaaCatalog/repository.html就是用来解决这个问题的。例如,您可能有:
public interface IWidgetRepository
{
// Query methods
Widget GetById(string id);
IEnumerable<Widget> GetAll();
// Update methods
void RenameWidget(string id, string newName);
void UpdateWidgetPrice(string id, decimal newPrice);
}
但是,如果您尝试使存储库接口变得非常通用,那么当您开始意识到您想要具有不同的查询功能等时,这很快就会变得令人畏惧(例如,如果您尝试在 DAL 中实现 IQueryable,那么您已经你还有很多工作要做!我已经尝试过,但我放弃了,意识到我只是在浪费精力。)
解决这个问题的最佳方法可能是预定义查询方法,例如GetWidgetsWithOpenOrders()
and GetWidgetsWithFooBarComponents
。然后在你的适配器类中实现IWidgetRepository
您只需通过将这些查询映射到实体框架或 WCF 服务实现来实现这些查询。
这样做的一个副作用是 DAL 将需要自己的一组数据传输对象 (DTO) - 因此您最终会在 DAL 命名空间中得到一个 Widget 类,并且可能在 DB Context 中拥有其他 Widget 类和/或 WCF 服务代理。您可以尝试通过强制数据库上下文使用相同的 Widget 类进行数据库映射来解决此问题,但我不建议这样做。 DB Context 中的 DTO 用于适应数据库,WCF 服务中的 DTO 也是如此 - 它们是服务公开的数据契约。 DAL 中的 DTO 反映了用户界面的需求(在 MVVM 术语中,它们是“模型”;在 OO 模式术语中,它们是Façade http://sourcemaking.com/design_patterns/facade不同的数据访问策略)。
另一个副作用是创建你的存根/模拟实现非常容易IWidgetRepository
1) 单元测试和 2) UI 快速原型设计,无需完全实施后端数据访问策略。