【问题标题】:In DDD where to keep custom exceptions (application exceptions)? In Infrastructure layer?在 DDD 中哪里保留自定义异常(应用程序异常)?在基础设施层?
【发布时间】:2020-08-30 04:34:35
【问题描述】:

我正在构建一个具有以下架构的应用程序:

UI - 应用程序 - 领域 - 基础架构

我有一个需要使用自定义异常的应用层。我将这些自定义异常保存在哪里?在基础设施层?问题是我的应用层没有对基础设施层的引用。

正确的方法是什么?

更新:

这是我在应用层中引发异常的代码:

public void InsertNewImage(ImagemDTO imagemDTO)
{
    if (isValidContentType(imagemDTO.ImageStreamContentType))
    {
        string nameOfFile = String.Format("{0}{1}", Guid.NewGuid().ToString(), ContentTypeHelper.GetExtension(imagemDTO.ImageStreamContentType));

        string path = String.Format("{0}{1}", ImageSettings.PathToSave, nameOfFile);

        _fileService.SaveFile(imagemDTO.ImageStream, path);

        Imagem imagem = new Imagem()
                            {
                                Titulo = imagemDTO.Titulo,
                                Descricao = imagemDTO.Descricao,
                                NomeArquivo = nameOfFile
                            };

        _imagemRepository.Add(imagem);

        _dbContext.SaveChanges();
    } else
    {
        throw new WrongFileTypeException(String.Format("{0} is not allowed.", ContentTypeHelper.GetExtension(imagemDTO.ImageStreamContentType)));
    }
}

甚至 ImageSettings 是 ConfigurationSection 在我的应用程序层中,因为它使用它。我没有看到其他方法可以将我的 ImageSettings(应该保留在基础设施层中)转移到基础设施层,有人可以帮忙吗?

public class ImageSettings : ConfigurationSection
{
    /// <summary>
    /// Caminha onde será salvo as imagens
    /// </summary>
    [ConfigurationProperty("pathToSave", IsRequired = true)]
    public string PathToSave
    {
        get { return (string)this["pathToSave"]; }
        set { this["pathToSave"] = value; }
    }

    /// <summary>
    /// Extensões permitidas pra upload
    /// </summary>
    [ConfigurationProperty("allowedExtensions", IsRequired = true)]
    public string AllowedExtensions
    {
        get { return (string)this["allowedExtensions"]; }
        set { this["allowedExtensions"] = value; }
    }

    /// <summary>
    /// Tamanho das imagens
    /// </summary>
    [ConfigurationProperty("imageSize")]
    public ImageSizeCollection ImageSize
    {
        get
        {
            return (ImageSizeCollection)this["imageSize"];
        }
    }
}

【问题讨论】:

    标签: .net domain-driven-design


    【解决方案1】:

    这很可能与您的previous question 有关。例外是合同的一部分,由应用层定义并由基础设施实现(DIP 和Onion architecture)。它们应该在应用程序术语中定义并由应用程序处理,但从基础设施抛出。例如,在您的应用程序代码中:

    public class NotificationException : Exception {...}
    
    public interface ICanNotifyUserOfSuccessfullRegistration {
        /// <summary>
        /// ...
        /// </summary>
        /// <exception cref="NotificationException"></exception>
        void Notify();
    }
    

    在基础设施方面:

    public class SmsNotificator : ICanNotifyUserOfSuccessfullRegistration {
        public void Notify() {
            try {
                // try sending SMS here
            } catch(SmsRelatedException smsException) {
                throw new NotificationException(
                                "Unable to send SMS notification.", smsException);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在 DDD 中哪里保存自定义异常(应用程序异常)?在基础设施层?

      • 没有

      为什么?

      • 在干净的架构中,中心层从不依赖于外部,总是相反
      • “基本规则是所有代码都可以依赖于更中心的层,但代码不能依赖于远离核心的层。换句话说,所有耦合都朝向中心。”。请查看来自 Jeffrey Palermo 的 article。

      我写了一篇关于 Onion Architecture 的文章,其中包含代码示例。请查看this。

      但基本上,您应该将自定义异常添加到您的层(在本例中为应用程序)。只需创建一个文件夹“Exceptions”,然后在其中添加您的用户定义的异常。请查看此链接了解我关于how to create user-defined exceptions的详细信息

      【讨论】:

        【解决方案3】:

        Acaz Souza - 你说应用层不应该引用基础设施层是不正确的。我建议你快速阅读 InfoQ 上免费提供的“领域驱动设计”。

        看下图,它说明了我的观点。

        谢谢

        【讨论】:

        • 嘿 Ronnie,这个图不是我理解的领域驱动设计,它是基础设施驱动的.. 域对象(项目)不应该依赖于 DDD 中的基础设施.. 使用 ORM 来生成 POCO 类和实体不需要依赖于基础设施(数据访问层)的项目,它是一个预处理、预构建关注点..
        • 就应用程序对基础架构的依赖而言.. 基础架构似乎涵盖了域和应用程序服务的实现以及对 sql 服务器、网关等的访问之外的关注点。也就是说,@ 987654322@ 不是 My 基础设施层的一部分,但它肯定是我的应用程序层所依赖的东西。所以我只能假设这张图将 .net 框架程序集指定为基础设施层的一部分。但这不是在您的域中实现任何东西的基础设施..所以它是可疑的..
        • 在《快速领域驱动设计》一书中,示例有应用层引用基础设施层,例如“应用层是介于用户界面、域和基础设施之间的薄层。它在登录操作期间与数据库基础设施交互......等等”(第 39 页)
        【解决方案4】:

        您是否有一个解决横切关注点(例如日志记录或依赖注入)的层,并且您的解决方案中的所有其他项目都引用了该层?如果是这样,这就是您应该放置这些自定义异常的地方。我猜你所说的“基础设施层”实际上是指这个横切层,但如果是这样,你的应用程序层没有引用它似乎很奇怪。

        或者,您可以将这些异常保留在应用程序层本身中,前提是这些异常仅由该层使用,也可能由 UI 层使用。

        【讨论】:

        • 基础设施参考应用。应用程序不参考基础设施。我认为这是正确的......
        猜你喜欢
        • 2010-10-16
        • 2011-11-30
        • 1970-01-01
        • 2021-12-29
        • 2021-12-18
        • 1970-01-01
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多