【问题标题】:Decoupling EF6 from its custom Api将 EF6 与其自定义 Api 解耦
【发布时间】:2014-11-28 17:04:47
【问题描述】:

我想就依赖注入和架构方法寻求一些帮助。

所以,我有一个由 EF6 实现的 ORM 层,其中描述了对象,Ef 做了它的业务等等。我在它上面创建了一个自定义库,称为 DatabaseApi,它在标题中被称为“Api”,其中我查询数据并将其映射到数据合同对象。我这样做是为了纯粹的测试目的。我希望我的应用程序中的不同库可测试。

我开始实现注入 DbContext 的代码,但我不知道如何处理这种情况下的使用。

我浏览了一些关于模拟和 EF 的博文和文章,尤其是 this one,但它更多的是关于测试 EF 本身,而不是关于如何将其与其他库分离。另一方面,我认为我的搜索关键字不正确。

您是否知道任何关于如何将实体框架与其他库解耦的优秀且有用的教程和文章?

提前致谢!

例子:

我创建了一个空接口以便 DbContext 可以被注入。它由databaseContext实现。

public interface IDatabase
{
}

public class DatabaseModelContext : DbContext, IDatabase{

    public DbSet<TableOne> TableOne { get; set; } 
    public DbSet<TableTwo> TableTwo { get; set; }

}

在自定义 Api 库构造函数中,我整理了一段代码来通过 Unity 解析接口。我不知道它是否有效。我还没有执行。

public partial class DatabaseApi : IDatabaseApi {
    private readonly IDatabase iDatabase;

    private readonly UnityContainer unityContainer;

    public DatabaseApi()
    {
        this.unityContainer = new UnityContainer();
        this.unityContainer.RegisterType<IDatabase, DatabaseModelContext>();
        this.iDiLibDatabase = this.unityContainer.Resolve<IDiLibDatabase>();
    }
}

这就是问题所在。由于注入,我将拥有和接口,但据我所知,有些用途对于管理资源很重要。怎么做?

public partial class DatabaseApi : IDatabaseApi
    {
        public List<SomeDataContract> GetMainStructure()
        {
            var result = new List<SomeDataContract>();

            //this is the old implementation
            using (var database = new DatabaseModelContext())
            {
                //some data manipulation magic... :)
            }
            return result;
        }

【问题讨论】:

  • 您可以在IDatabase 中声明IDbSet&lt;T&gt; 成员并显式实现它们。对于using...dispose,您必须使用处理一次性对象的 IOC 容器。 Unity 并没有开箱即用,但如果您搜索它,则有一个适用于 Unity 的 TransientDisposableLifetimeManager 的实现。我不知道其他 IOC 容器。
  • 基思,感谢您的建议。根据您的建议,我找到了 AutoFac 以及有关它的有趣文章和教程。谢谢!我找到了解决我的问题的方法! :) stackoverflow.com/questions/987761/… github.com/autofac/Autofac codeproject.com/Articles/25380/…
  • Keith,如何将您的答案标记为我正在寻找的解决方案?
  • 由于我只有一个有用的评论,而您自己找到了问题的答案,您应该发布一个解释您找到的答案的答案,可能包括您自己的一些代码,并将其标记为答案.这样,其他可能正在寻找相同或类似问题答案的人也可以找到您的答案。
  • 尝试查看存储库模式。即这里:codeproject.com/Articles/526874/…

标签: c# entity-framework dependency-injection decoupling


【解决方案1】:

如果您可以将 linq to objects 用作域访问层的核心元素,那么公开 IQueryable 以访问实体就可以了...

public interface IRepository<TEntity>
{
  IQueryable<TEntity> AllEntities { get; }
}

有了它,您可以在不直接连接到 EF 的情况下执行 Where、Select 等操作。在幕后,IRepository 实现将处理 EF 部分、数据库连接等。无法避免在数据访问层与 EF 耦合。但是您可以使用您已经开始的方法将其限制在该层。只需确保您的 IRepository 对象使用的数据库上下文是唯一使用 EF 的对象。

换一种说法:不要让您的 IDatabase 返回实体。只需让它处理连接,您应该创建另一个用于域对象访问的层,该层接受一个 IDatabase。在我给出的示例中,IRepository 实现会以某种方式接受 IDatabase 的实例。

【讨论】:

  • 很遗憾,当您尝试使用不同的实体执行工作单元时,这无效。
【解决方案2】:

因此,解决方案是使用 Autofac DI 框架。我发现了有趣的问题和答案以及两个非常有用的教程。以下链接:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多