C# 服务层与DAL层交互的设计问题
我的项目有一个设计问题,我不知道如何解决,我有一个保存存储库的DAL层和一个保存“处理器”的服务层。处理器的作用是提供对DAL数据的访问,并执行一些验证和格式化逻辑 我的域对象都至少有一个来自服务层的对象的引用(从存储库中检索它们的属性值)。然而,我面临两个周期性依赖。第一个“循环依赖”来自我的设计,因为我希望DAL返回域对象——我的意思是它是概念性的——第二个来自我的代码C# 服务层与DAL层交互的设计问题,c#,asp.net-mvc,ef-code-first,onion-architecture,C#,Asp.net Mvc,Ef Code First,Onion Architecture,我的项目有一个设计问题,我不知道如何解决,我有一个保存存储库的DAL层和一个保存“处理器”的服务层。处理器的作用是提供对DAL数据的访问,并执行一些验证和格式化逻辑 我的域对象都至少有一个来自服务层的对象的引用(从存储库中检索它们的属性值)。然而,我面临两个周期性依赖。第一个“循环依赖”来自我的设计,因为我希望DAL返回域对象——我的意思是它是概念性的——第二个来自我的代码 域对象始终至少依赖于一个服务对象 域对象通过调用服务上的方法从存储库中检索其属性 服务的方法调用DAL 然而,问题是,当D
using Core;
public Repo : IRepoComplexClass1
{
MyComplexClass1 GetMyComplexClassList1()
{
//Retrieve all the stuff...
//... And now it's time to convert the DTOs to Domain Objects
//I need to write
//DomainObject.Property1 = new MyComplexClass1(ID, Service);
//So my Repository has a dependency with my service and my service has a dependency with my repository, (Because my Service Methods, make use of the Repository). Then, Ninject is completely messed up.
}
我希望现在更清楚。首先,在设计系统时,像and(DDD)这样的典型体系结构指南并不适合所有情况。事实上,不鼓励使用这些技术,除非领域具有足够的复杂性来保证成本。因此,您正在建模的领域非常复杂,无法适应更简单的模式 IMHO,洋葱架构和DDD都试图实现相同的目标。也就是说,能够为复杂逻辑提供一个可编程(并且可能易于移植)的域,而不需要考虑所有其他问题。这就是为什么在洋葱中,应用程序、基础设施、配置和持久性问题处于边缘 总之,域只是代码。然后,它可以利用这些酷的设计模式来解决手头的复杂问题,而不必担心其他任何事情 我真的很喜欢洋葱的文章,因为同心屏障的图片不同于分层架构的想法 在分层体系结构中,很容易通过各层进行垂直、上下思考。例如,您在上面有一个服务,它(通过DTO或ViewModels)与外部世界对话,然后该服务调用业务逻辑,最后,业务逻辑向下调用某个持久层以保持系统的状态 然而,洋葱架构描述了一种不同的思考方式。您可能仍然在顶部有一个服务,但这是一个应用程序服务。例如,ASP.NET MVC中的控制器了解HTTP、应用程序配置设置和安全会话。但控制器的工作不仅仅是将工作推迟到较低(更智能)的层。任务是尽可能快地从应用程序端映射到域端。简单地说,控制器调用域,要求执行一段复杂的逻辑,得到结果,然后继续执行。控制器是将事物连接在一起的粘合剂(而不是域) 因此,域是业务域的中心。没有别的了 这就是为什么有些人抱怨ORM工具需要域实体上的属性。我们希望我们的领域完全没有任何问题,除了手头的问题。所以,普通的旧物体 因此,域不直接与应用程序服务或存储库对话。事实上,域调用的没有任何东西能说明这些事情。域是核心,因此是执行堆栈的末尾 因此,对于一个非常简单的代码示例(改编自OP): 存储库:
// it is only infrastructure if it doesn't know about specific types directly
public Repository<T>
{
public T Find(int id)
{
// resolve the entity
return default(T);
}
}
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; } // requred because cannot be set from outside
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
// no dependency injection frameworks!
public MyComplexClass1(MyComplexClass1 property1)
{
// actually using the constructor to define the required properties
// MyComplexClass1 is required and MyComplexClass2 is optional
this.Property1 = property1;
.....
}
public ComplexCalculationResult CrazyComplexCalculation(MyComplexClass3 complexity)
{
var theAnswer = 42;
return new ComplexCalculationResult(theAnswer);
}
}
public class TheController : Controller
{
private readonly IRepository<MyComplexClass1> complexClassRepository;
private readonly IRepository<ComplexResult> complexResultRepository;
// this can use IoC if needed, no probs
public TheController(IRepository<MyComplexClass1> complexClassRepository, IRepository<ComplexResult> complexResultRepository)
{
this.complexClassRepository = complexClassRepository;
this.complexResultRepository = complexResultRepository;
}
// I know about HTTP
public void Post(int id, int value)
{
var entity = this.complexClassRepository.Find(id);
var complex3 = new MyComplexClass3(value);
var result = entity.CrazyComplexCalculation(complex3);
this.complexResultRepository.Save(result);
}
}
控制器(应用程序服务):
// it is only infrastructure if it doesn't know about specific types directly
public Repository<T>
{
public T Find(int id)
{
// resolve the entity
return default(T);
}
}
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; } // requred because cannot be set from outside
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
// no dependency injection frameworks!
public MyComplexClass1(MyComplexClass1 property1)
{
// actually using the constructor to define the required properties
// MyComplexClass1 is required and MyComplexClass2 is optional
this.Property1 = property1;
.....
}
public ComplexCalculationResult CrazyComplexCalculation(MyComplexClass3 complexity)
{
var theAnswer = 42;
return new ComplexCalculationResult(theAnswer);
}
}
public class TheController : Controller
{
private readonly IRepository<MyComplexClass1> complexClassRepository;
private readonly IRepository<ComplexResult> complexResultRepository;
// this can use IoC if needed, no probs
public TheController(IRepository<MyComplexClass1> complexClassRepository, IRepository<ComplexResult> complexResultRepository)
{
this.complexClassRepository = complexClassRepository;
this.complexResultRepository = complexResultRepository;
}
// I know about HTTP
public void Post(int id, int value)
{
var entity = this.complexClassRepository.Find(id);
var complex3 = new MyComplexClass3(value);
var result = entity.CrazyComplexCalculation(complex3);
this.complexResultRepository.Save(result);
}
}
public类控制器:控制器
{
私有只读IRepository complexClassRepository;
私有只读IRepository complexResultRepository;
//如果需要,可以使用IoC,没有问题
公共控制器(IRepository complexClassRepository、IRepository complexResultRepository)
{
this.complexClassRepository=complexClassRepository;
this.complexResultPostory=complexResultPostory;
}
//我知道HTTP
公共作废帖子(int-id,int-value)
{
var entity=this.complexClassRepository.Find(id);
var complex3=新的MyComplexClass3(值);
var结果=实体.CrazyComplexCalculation(complex3);
this.complexResultRepository.Save(结果);
}
}
现在,你很快就会想,“哇,那个控制器做得太多了”。例如,如果我们需要50个值来构造MyComplexClass3
,怎么样。这就是洋葱建筑的辉煌之处。那里