我将一个 POC 项目分配给了一个要求实现命令查询分离、控制反转(使用依赖注入)和存储库模式的人。“某人”给了我一个 POC 解决方案项目,但我不确定这是否是这样做的。在这里简单介绍一下POC项目
- 该项目是一个简单的 3 层应用程序——表示层 (PL)、业务逻辑层 (BLL) 和数据访问层 (DAL);每一层都是一个单独的项目
- 表示层是 Web 应用程序,BLL 和 DAL 是类库项目
- 在业务层中,定义了存储库接口。BLL 库的引用被添加到 DAL 项目中,并且在 DAL 项目中有实现存储库接口的具体类。这就是应用控制反转的方式
- 由于完成了 Command-Query-Separation,业务层中的存储库接口只声明了 Add/Update 和 Delete 方法。对于读取,直接在 DAL 中有“读取”接口,在 DAL 中有实现这些接口的具体类。
- 表示层包含对 BLL 库和 DAL 库的引用。对 Add/Update/Delete 的调用通过 BLL 路由到 DAL,而任何读取都直接从 DAL 完成。我相信这符合绕过 BLL 进行读取的 Command-Query-Separation 概念。
这是所有设置的说明。有三个项目
- 西北网
- 西北商业
- 西北数据访问
下面是不同层中的代码快照。
-- 西北网 --
// A class in the Presentation Layer
public class CustomerPage
{
// Business layer Interface from NW.Business namespace
private ICustomerBusiness ICustB;
//DAL Read interface from NW.DataAccess.Read namepsace
private ICustomerRead<Guid> ICustR;
//Constructor for the Customer Page that uses Constructor Injection
public CustomerPage(ICustomerBusiness ICustB, ICustomerRead<Guid> ICustR)
{
this.ICustB = ICustB;
this.ICustR = ICustR;
}
}
-- 西北商业 --
//Declaration of business interface in the Business Layer
interface ICustomerBusiness
{
void Persist();
}
// A class in the Business Layer that implements the business interface
public class Customer: ICustomerBusiness
{
//Repository interface object that will be injected by Constructor Injection.
private ICustomerRepository ICustRep;
public Customer(ICustomerRepository ICustRep)
{
this.ICustRep = ICustRep;
}
public void Persist()
{
ICustRep.AddOrUpdate();
}
}
//Declaration of Repository interface in the Business Layer
public interface ICustomerRepository
{
void AddOrUpdate();
void Delete();
}
-- NW.DataAccess--
public class CustomerRepository : ICustomerRepository
{
public void AddOrUpdate()
{
//implementation of Add or Update
}
public void Delete()
{
//implementation of Delete
}
}
//A Read interface in the Data Access Layer
interface ICustomerRead<T>
{
// A read is returned as DTO since in Database this may map to more than 1 table
CustomerDTO GetCustomerDetails(T id);
}
// An implementation of the Read Interface in the Data Access Layer
namespace NW.DataAccess.Read
{
public class CustomerRead<T> : ICustomerRead<T>
{
public CustomerDTO GetCustomerDetails(T id)
{
//implementation here
}
}
}
我的直觉是这里有问题。似乎 CQRS 或至少上述实现没有解决某些要求
- 客户业务对象(客户类)可能需要从数据库中读取其内部目的(如初始化变量等)。在 DAL 层中直接定义读取,唯一的方法是引用 BLL 中的 DAL dll。但这会创建循环引用并违背已完成的 IOC
- 当所有业务对象都存在一些共同的读取需求时会发生什么?
有什么建议么 ?