针对接口和实体框架4.0进行编程

Tim*_*sig 7 .net c# entity-framework interface entity-framework-4

我试图弄清楚是否有可能坚持"针对接口而不是实现的程序"的口头禅.使用Entity Framework 4.0时.

虽然我找到了一个页面,解释了如何在使用Linq-to-SQL时坚持上述规则(请看这里),但我非常想知道是否可以使用实体框架(也使用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
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想像这样使用它:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

本质上,我希望能够通过使用接口将实体框架的DataContext传递出它所实现的程序集/子系统.数据上下文提供的所有信息都应以接口的形式出现,而不是实际的类.

我想保持实际的类在程序集内部实现实体,只暴露它们实现的接口.

这可能与实体框架有关吗?如果没有,是否有其他O/R映射器可以这种方式使用?

如果这不是一个如何进一步将数据库与实际应用程序分离的好方法,那么我很想听听您的建议.

RPM*_*984 6

更好的解决方案(在我看来)是做以下事情:

为您的实体数据模型创建存储库,公开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
Run Code Online (Sandbox Code Playgroud)

由于接口,你可以交换进入模拟,其他ORM:

public class MockRepo : IRepository
{ 
   public List<Person> persons; // mimics entity set
}
Run Code Online (Sandbox Code Playgroud)

只有这么多你可以抽象出来.

如果您担心使用ObjectSet(与EF绑定),请使用POCO.

请查看我的其他一些问题以获取更多信息(因为我们现在正在构建此架构).

另外,请考虑使用依赖注入.在这里,您可以从管理ObjectContext的业务中获取存储库 - 您可以将存储库注入工作单元(它是ObjectContext的包装器 - 因此多个存储库或聚合根可以处理相同的上下文).

在我们的解决方案中,除了存储库之外,没有任何内容涉及实体框架(或任何持久性逻辑),这些存储库位于单独的程序集中.

HTH.