域层是否应该直接接收依赖关系DTO?

时间:2014-08-28 13:43:14

标签: c# asp.net-web-api domain-driven-design data-access-layer

之前可能已经提出过这个问题,但我正在访问数据访问层中的依赖Web服务,我需要问我是否应该将从该服务返回的DTO重新打包到我自己的DTO中? UI层是具有控制器的WebAPI项目,域和数据访问层是单独的C#项目。在每个层中引用依赖Web服务是否正确,以便dal,biz和domain层都具有相应的代码引用,或者我应该创建自己的DAL层中Web服务返回的DTO视图?

1 个答案:

答案 0 :(得分:0)

从DDD的角度来看,我每次都以类似的方式做到这一点。我倾向于使用Ports&适配器在经典的分层架构上键入架构。主要是因为它允许我通过IoC连接的接口轻松引用我的持久层。这提供了几乎双向引用,我不仅可以从我的域访问我的持久层,而且可以在我的持久层中使用我的域模型。

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

例如,在我所在的项目中,我正在进行地理编码(查找邮政编码到坐标中),在我的域模型中名为 Geographical 的文件夹中,我有一个名为<的接口EM> 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服务的事实也是隐藏的。

相关问题