C# 实体框架循环dll引用
当前(sad)状态下的我的解决方案: 我希望我的业务层数据提供程序是不可知的(这不是一件好事吗?),只有一个接口,这样我就可以使用NHibernate或Linq-to-Xml或我或我的老板想要使用的任何类型的持久性提供程序(或在项目完成后2秒不可避免地发明的新的高级提供程序)C# 实体框架循环dll引用,c#,entity-framework,circular-reference,C#,Entity Framework,Circular Reference,当前(sad)状态下的我的解决方案: 我希望我的业务层数据提供程序是不可知的(这不是一件好事吗?),只有一个接口,这样我就可以使用NHibernate或Linq-to-Xml或我或我的老板想要使用的任何类型的持久性提供程序(或在项目完成后2秒不可避免地发明的新的高级提供程序) IPersistenceProvider就是这个接口,我可以用Unity(而不是游戏平台,DI容器)注入它。对我来说,IPersistenceProvider属于数据层,我们可以继续添加文件夹(如EntityFramew
IPersistenceProvider
就是这个接口,我可以用Unity(而不是游戏平台,DI容器)注入它。对我来说,IPersistenceProvider
属于数据层,我们可以继续添加文件夹(如EntityFramework
),因为我的简历(或项目)中需要添加新的持久性范例
因此,我的业务dll依赖于我的数据dll。以下是业务dll中的一些代码,具体取决于数据dll:
使用系统;
使用Atlas.Data.Kernel;
命名空间Atlas.Business.Kernel
{
公共抽象类BusinessObject
{
公共业务对象(IPersistenceProvider p)
{
}
公共Guid Id;
}
}
我还觉得我的DatabaseContext
属于数据层。但是EF让您为它的DbSet
s引用具体类型,这意味着Atlas数据内核dll需要依赖于Atlas业务内核dll,这将形成一个循环dll引用。En plus(法语的意思)是指业务层具体类型的数据层DatabaseContext
希望在业务dll中运行,但这将我的业务层与特定的持久性策略工件耦合在一起
如何解决这个问题?我可以把它折叠成一个dll(事实上,我在以前的一个项目中就是这么做的),但那有点糟糕,我将无法进入.Net架构师俱乐部。他们会嘲笑我的“1N太少”架构,并嘲笑我退出会议。WWD?(Dino Esposito会怎么做?将声明与实现分离
EntityFramework
子目录应该是一个单独的程序集(例如AtlasDataKernelEF),其中包含EF内容和IPersistenceProvider的实现,从而解析循环引用
此外,如果您确实需要使用不同的ORM,您可以将生产可执行文件从所有EF库中删除
您没有描述如何实例化EF数据访问,但您肯定需要将其封装在某种工厂类中。从实现中拆分声明
EntityFramework
子目录应该是一个单独的程序集(例如AtlasDataKernelEF),其中包含EF内容和IPersistenceProvider的实现,从而解析循环引用
此外,如果您确实需要使用不同的ORM,您可以将生产可执行文件从所有EF库中删除
您没有描述如何实例化EF数据访问,但您确实需要将其封装在某种工厂类中。您的项目AtlasBusinessKernel不应该引用AtlasTakernal类中的任何资源。AtlasBusinessKernel项目中AtlasDataKernel中需要使用的任何资源都应该表示为接口,可以是IDataContext接口或存储库接口
只有当您有第三个实际使用AtlasBusiness内核项目的项目时,这才有效,可能是表示UI的web应用程序或控制台应用程序。这个项目将负责实例化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);
}
}
您的项目AtlasBusinessKernel不应引用AtlasDatakernal类中的任何资源。AtlasBusinessKernel项目中AtlasDataKernel中需要使用的任何资源都应该表示为接口,可以是IDataContext接口或存储库接口
只有当您有第三个实际使用AtlasBusiness内核项目的项目时,这才有效,可能是表示UI的web应用程序或控制台应用程序。这个项目将负责实例化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);
}
}
IPersistenceProvider的目的是什么?@SergeyBerezovskiy,它是桥接OO模式中的桥接接口/抽象。具体的持久性提供程序(例如,EFPersistenceProvider
)将实现它。您的逻辑(需要循环依赖)似乎有缺陷,或者您的模式选择不适合这项工作。也就是说,我根本不明白你为什么需要依赖于业务层。不清楚,也许你应该做一个小项目,用具体的类来展示它。任何数据提供者(接口)都应该只提供接口的通用方式,或POCO等。@NSGaga,EF需要具体参考业务类型来建立“模型”(DbContext
),例如:public virtual DbSet Categories{get;set;}
IPersistenceProvider的用途是什么?@SergeyBerezovskiy,它是桥接OO模式中的桥接接口/抽象。具体的持久性提供程序(例如,EFPersistenceProvider
)将实现它。您的逻辑(需要循环依赖)似乎有缺陷,或者您的模式选择不适合这项工作。也就是说,我根本不明白你为什么需要依赖于业务层。不清楚,也许你应该做一个小项目,用具体的类来展示它。任何数据提供者(接口)都应该只提供接口或POCO等的通用方式。@NSGaga,EF需要具体参考业务类型来建立“模型”(DbContext
),例如:public virtual DbSet Categories{get;set;}
,以澄清,AtlasDataKernelDataEF
将取决于atlaskernelbusiness
和atlaskerneldata
<代码>AtlasKernalData
和