域层是否应该直接接收依赖DTO
本文关键字:依赖 DTO 是否 | 更新日期: 2023-09-27 18:20:01
以前可能有人问过这个问题,但我正在访问数据访问层中的依赖web服务,我需要问是否应该将该服务返回的DTO重新打包为我自己的DTO?UI层是一个带有控制器的WebAPI项目,域和数据访问层是单独的C#项目。引用每一层中的依赖web服务以使dal、biz和域层都具有适当的代码引用是正确的吗?还是我应该创建自己的视图来查看从dal层中的web服务返回的DTO?
从DDD的角度来看,我每次都以类似的方式这样做。我倾向于使用Ports&适配器类型的体系结构优于经典的分层体系结构。主要是因为它允许我通过IoC连接的接口轻松地引用我的持久层。这几乎提供了一个双向引用,在这里我不仅可以从我的域访问我的持久层,而且可以在我的持久性层中使用我的域模型。
我在访问外部web服务时所做的操作非常相似。我设置了一个新的适配器,并将访问外部服务的接口放在我的域中,然后使用IoC将其连接起来。然后,我可以访问外部web服务,使用一些通常在我这边(客户端)自动生成(或手工制作)的DTO,然后将这些DTO映射到我的域对象。
例如,在我正在进行地理编码(将邮政编码查找到坐标中)的项目中,在我的域模型中名为Geographical的文件夹中,我有一个名为IGeocodingService:的接口
namespace Booking.Domain.Model.Geographical
{
/// <summary>
/// The <see cref="IGeocodingService" /> interface.
/// </summary>
public interface IGeocodingService
{
/// <summary>
/// Performs a postal code query.
/// </summary>
/// <param name="countryIsoCode">The country iso code.</param>
/// <param name="postalCode">The postal code.</param>
/// <returns>A geographic coordinate.</returns>
Coordinate PostalCodeQuery(string countryIsoCode, string postalCode);
}
}
在一个名为Booking.Adapter.CloudMade的单独项目中,我有一个名称为CloudMadeGeocodingService,它继承自IGeocodingService:
namespace Booking.Adapter.CloudMade
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Booking.Domain.Model.Geographical;
/// <summary>
/// The <see cref="CloudMadeAdapter" /> class.
/// </summary>
public class CloudMadeGeocodingService : IGeocodingService
{
/// <summary>
/// Performs a postal code query.
/// </summary>
/// <param name="countryIsoCode">The country iso code.</param>
/// <param name="postalCode">The postal code.</param>
/// <returns>
/// A geographic coordinate.
/// </returns>
public Coordinate PostalCodeQuery(string countryIsoCode, string postalCode)
{
string country;
switch (countryIsoCode)
{
case "GB":
country = "UK";
break;
default:
country = null;
break;
}
if (country == null)
{
return null;
}
using (HttpClient httpClient = new HttpClient())
{
// TODO: Make call to CloudMade v2 geocoding API.
}
// TODO: Remove this.
return null;
}
}
}
从我的领域来看,用这种方式做事有两大优势。第一种是服务包装将自己呈现为某种外部组件,第二种是它接受并返回本机C#.NET类型或我自己的域模型类型。实现是隐藏的,在这种情况下,如果需要任何DTO(在本例中没有),并且数据来自Web API Web服务的事实也被隐藏。