C# 域层是否应该直接接收依赖项DTO?

C# 域层是否应该直接接收依赖项DTO?,c#,asp.net-web-api,domain-driven-design,data-access-layer,C#,Asp.net Web Api,Domain Driven Design,Data Access Layer,以前可能会问这个问题,但我正在访问数据访问层中的依赖项web服务,我需要问是否应该将从该服务返回的DTO重新打包到我自己的DTO中?UI层是一个带有控制器的WebAPI项目,域和数据访问层是独立的C#项目。引用每个层中的依赖关系web服务是否正确,以便dal、biz和域层都具有适当的代码引用,或者我是否应该创建自己对dal层中web服务返回的DTO的视图?从DDD的角度来看,我每次都以类似的方式这样做。我倾向于使用端口和适配器类型的体系结构,而不是传统的分层体系结构。主要是因为它允许我通过IoC

以前可能会问这个问题,但我正在访问数据访问层中的依赖项web服务,我需要问是否应该将从该服务返回的DTO重新打包到我自己的DTO中?UI层是一个带有控制器的WebAPI项目,域和数据访问层是独立的C#项目。引用每个层中的依赖关系web服务是否正确,以便dal、biz和域层都具有适当的代码引用,或者我是否应该创建自己对dal层中web服务返回的DTO的视图?

从DDD的角度来看,我每次都以类似的方式这样做。我倾向于使用端口和适配器类型的体系结构,而不是传统的分层体系结构。主要是因为它允许我通过IoC连接的接口轻松地引用我的持久层。这几乎提供了一个双向引用,在这里我不仅可以从我的域访问我的持久层,而且可以在持久层中使用我的域模型

我在访问外部web服务时所做的工作非常类似。我设置了一个新的适配器,并将用于访问外部服务的接口放在我的域中,然后使用IoC将其连接起来。然后,我可以使用一些DTO访问外部web服务,这些DTO通常是在我这边(客户端)自动生成(或手工制作)的,然后将它们映射到我的域对象

例如,在我的一个项目中,我正在进行地理编码(将邮政编码查找到坐标中),在我的域模型中的一个名为geographic的文件夹中,我有一个名为IGeocodingService的接口:

namespace.Domain.Model.geographic
{
/// 
///界面。
/// 
公共接口服务
{
/// 
///执行邮政编码查询。
/// 
///国家iso代码。
///邮政编码。
///地理坐标。
坐标postalCode查询(字符串countryIsoCode,字符串postalCode);
}
}
在一个名为Booking.Adapter.CloudMade的单独项目中,我有一个名为CloudMadeGeocodingService的服务,该服务继承自IGeocodingService:

namespace Booking.Adapter.CloudMade
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Net.Http;
使用系统文本;
使用System.Threading.Tasks;
使用Booking.Domain.Model.geographic;
/// 
///这个班。
/// 
公共类CloudMadeGeocodingService:IGeocodingService
{
/// 
///执行邮政编码查询。
/// 
///国家iso代码。
///邮政编码。
/// 
///地理坐标。
/// 
公共坐标postalCode查询(字符串countryIsoCode,字符串postalCode)
{
弦国;
开关(等码)
{
案例“GB”:
国家=“英国”;
打破
违约:
国家=空;
打破
}
如果(国家==null)
{
返回null;
}
使用(HttpClient HttpClient=new HttpClient())
{
//TODO:调用CloudMake v2地理编码API。
}
//TODO:删除此项。
返回null;
}
}
}

从我所在领域的角度来看,以这种方式做事有两大优势。第一个是服务包装将自己呈现为某种外部组件,第二个是它接受并返回本机C#.NET类型或我自己的域模型类型。实现是隐藏的,在本例中,如果需要任何DTO(在本例中没有),并且数据来自Web API Web服务的事实也是隐藏的。

谢谢。我的问题是,外部web服务返回的是相当复杂的对象,而不是字符串等简单的值。因此,我可以选择在每个项目中引用外部WS,我可能需要使用它的数据,因此能够引用它的DTO类型,或者将外部WS封装在内部服务类中(适配器,是吗?)并将它的DTO数据重新打包到我自己的DTO中。我们目前在其他地方使用AutoMapper,因此我认为这是重新打包web服务数据的更好方法。主要问题是WS不应该到处引用。
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);
    }
}
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;
        }
    }
}