我正在试图弄清楚是否有可能坚持“针对接口而不是实现的程序”的口头禅.使用Entity Framework 4.0时.
虽然我在使用Linq-to-sql(look here)时发现了一个解释如何坚持上述规则的页面,但我非常想知道是否可以使用实体框架(也使用Linq)来实现这一点.
这是它通常使用的方式:
var query = from pages in dataContext.Pages where pages.IsPublished select pages; foreach (Page page in query) { // do something with page... var routeQuery = from routes in page.Route where route.IsValid select routes; foreach (Route route in routeQuery) { // do something with route } }
但我想像这样使用它:
var query = from pages in dataContext.Pages where pages.IsPublished select pages; foreach (IPage page in query) { // do something with page... var routeQuery = from routes in page.Route where route.IsValid select routes; foreach (IRoute route in routeQuery) { // do something with route } }
本质上,我希望能够通过使用接口将实体框架的DataContext传递出它所实现的程序集/子系统.数据上下文提供的所有信息都应以接口的形式出现,而不是实际的类.
我想保持实际的类实现程序集内部的实体,只暴露它们实现的接口.
实体框架是否可以实现这一目标?如果没有,是否有其他O / R映射器可以这种方式使用?
解决方法
那么一个更好的解决方案(在我看来),是做以下事情:
为您的实体数据模型创建存储库,公开ICollection< T>或IQueryable< T>
使用存储库中的接口:
public interface IRepository { public ICollection<Person> Find(string name); // tighter,more maintanability public IQueryable<Person> Find(); // full power! but be careful when lazy loading
由于接口,你可以交换进入模拟,其他ORM:
public class MockRepo : IRepository { public List<Person> persons; // mimics entity set }
只有这么多你可以抽象出来.
如果您担心使用ObjectSet(与EF绑定),请使用POCO.
请查看我的其他一些问题以获取更多信息(因为我们现在正在构建此架构).
另外,考虑使用依赖注入.在这里,您可以从管理ObjectContext的业务中获取存储库 – 您可以将存储库注入工作单元(它是ObjectContext的包装器 – 因此多个存储库或聚合根可以处理相同的上下文).
在我们的解决方案中,除了存储库之外,没有任何内容涉及实体框架(或任何持久性逻辑),这些存储库位于单独的程序集中.
HTH.