我的解决方案是当前(悲伤)状态:
我希望我的业务层数据提供者不可知(这不是一件好事吗?)只有一个接口所以我可以将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会做什么?)
答案 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);
}
}