我目前有一个基于ASP.NET网站的文章使用服务层进行验证的服务层。
根据这个答案,这是一种不好的方法,因为服务逻辑与验证逻辑混合在一起,违反了单一职责原则。
我真的很喜欢提供的替代方案,但在重构我的代码时,我遇到了一个无法解决的问题。
考虑以下服务接口:
传递给验证器的
如果用户提供的详细信息不对应于数据库中的实体,则
我遇到的问题是,在此阶段,验证器已经失去了上下文信息(零件号和供应商名称),因此无法向用户报告准确的错误。我能提供的最佳错误类似于“购买订单必须有关联的零件”,但这对用户来说没有意义,因为他们确实提供了零件号(只是不存在于数据库中)。
使用ASP.NET文章中的服务类,我正在执行以下操作:
这使我能够向用户提供更好的验证信息,但意味着验证逻辑直接包含在服务类中,违反了单一责任原则(代码也在服务类之间重复)。
有没有办法做到两者兼顾?我能否将服务层与验证层分离,同时仍提供相同级别的错误信息?
根据这个答案,这是一种不好的方法,因为服务逻辑与验证逻辑混合在一起,违反了单一职责原则。
我真的很喜欢提供的替代方案,但在重构我的代码时,我遇到了一个无法解决的问题。
考虑以下服务接口:
interface IPurchaseOrderService
{
void CreatePurchaseOrder(string partNumber, string supplierName);
}
根据链接的答案,以下是具体的实现:
public class PurchaseOrderService : IPurchaseOrderService
{
public void CreatePurchaseOrder(string partNumber, string supplierName)
{
var po = new PurchaseOrder
{
Part = PartsRepository.FirstOrDefault(p => p.Number == partNumber),
Supplier = SupplierRepository.FirstOrDefault(p => p.Name == supplierName),
// Other properties omitted for brevity...
};
validationProvider.Validate(po);
purchaseOrderRepository.Add(po);
unitOfWork.Savechanges();
}
}
传递给验证器的
PurchaseOrder
对象还需要两个其他实体:Part
和Supplier
(在此示例中,假设PO仅具有单个零件)。如果用户提供的详细信息不对应于数据库中的实体,则
Part
和Supplier
对象都可以为null,这将要求验证器抛出异常。我遇到的问题是,在此阶段,验证器已经失去了上下文信息(零件号和供应商名称),因此无法向用户报告准确的错误。我能提供的最佳错误类似于“购买订单必须有关联的零件”,但这对用户来说没有意义,因为他们确实提供了零件号(只是不存在于数据库中)。
使用ASP.NET文章中的服务类,我正在执行以下操作:
public void CreatePurchaseOrder(string partNumber, string supplierName)
{
var part = PartsRepository.FirstOrDefault(p => p.Number == partNumber);
if (part == null)
{
validationDictionary.AddError("",
string.Format("Part number {0} does not exist.", partNumber);
}
var supplier = SupplierRepository.FirstOrDefault(p => p.Name == supplierName);
if (supplier == null)
{
validationDictionary.AddError("",
string.Format("Supplier named {0} does not exist.", supplierName);
}
var po = new PurchaseOrder
{
Part = part,
Supplier = supplier,
};
purchaseOrderRepository.Add(po);
unitOfWork.Savechanges();
}
这使我能够向用户提供更好的验证信息,但意味着验证逻辑直接包含在服务类中,违反了单一责任原则(代码也在服务类之间重复)。
有没有办法做到两者兼顾?我能否将服务层与验证层分离,同时仍提供相同级别的错误信息?