实体框架循环dll参考

时间:2017-02-18 22:19:51

标签: c# entity-framework circular-reference

我的解决方案是当前(悲伤)状态:

My solution in it's current state

我希望我的业务层数据提供者不可知(这不是一件好事吗?)只有一个接口所以我可以将NH与NHibernate或Linq切换到Xml或任何类型的持久性提供者我或我的老板想要使用(或在该项目完成后2秒内不可避免地会发明的新的优质产品)。

IPersistenceProvider就是那个界面,我可以用Unity注入它(不是游戏平台,DI容器)。对我而言,IPersistenceProvider属于数据层,我们可以继续添加文件夹(如EntityFramework),因为需要将新的持久性范例添加到我的简历(或项目)中。

因此,我的业务dll取决于我的数据dll。这是业务dll中的一些代码,具体取决于数据dll:

using System;
using Atlas.Data.Kernel;

namespace Atlas.Business.Kernel
{
  public abstract class BusinessObject
  {
    public BusinessObject(IPersistenceProvider p)
    {

    }


    public Guid Id;

  }
}

我也觉得我的DatabaseContext属于数据层。但EF让你引用其DbSet的具体类型,这意味着Atlas 数据内核dll需要依赖于Atlas Business 内核dll,会做一个圆形的dll引用。 En plus(这也是法语),一个指向Business Layer具体类型的数据层东西让我闻到了。 DatabaseContext希望在业务dll中生效,但这会将我的业务层与特定的持久性策略工件耦合。

如何解决这个问题?我可以将它折叠成一个dll(事实上,我在之前的项目中做了那件事),但是那有点糟透了,我将无法进入.Net Architects俱乐部。他们会嘲笑我的“1 N太少”的架构,并在会议中嘲笑我。 WWDED? ( Dino Esposito会做什么?

2 个答案:

答案 0 :(得分:1)

从实施中拆分声明。

EntityFramework子目录应该是一个单独的程序集(例如AtlasDataKernelEF),其中包含EF内容和IPersistenceProvider的实现,从而解析循环引用。

此外,如果您真的需要使用不同的ORM,那么您可以将生产可执行文件排除在所有EF库之外。

您没有草拟如何实例化EF数据访问,但您肯定需要将其包装在某种工厂类中。

答案 1 :(得分:1)

您的项目AtlasBusinessKernel不应该引用AtalsDataKernal类中的任何资源。 AtalsBusinessKernel需要使用的AtalsDataKernal中的任何资源都应该表示为AtalasBusinessKernal项目中的接口,可以是IDataConext接口或存储库接口。

仅当您有第三个实际使用AtalsBusinessKernal项目的项目(可能是Web应用程序或代表UI的控制台应用程序)时,此方法才有效。该项目将负责实例化DatabaseContext,最好使用DI。

// In your AtlasDataKernal
public class DatabaseContext : IDataContext
{
      // implementation
}

// In your AtlasBusinessKernal
public class MyBusinessLogic
{
     private IDataContext dataContext;
     public MyBusinessLogic(IDataContext context)
     {
        this.dataContext = context;
     }
}
// In your web application or whatever project type it might be
public class MyWebApp
{
      public DoSomeThing()
      {
          IDataContext context = new DatabaseContext();
          MyBusinessLogic logic = new MyBusinessLogic(context);
      }
}