c# - 在分层架构中,应用层如何知道 Web URL?

标签 c# .net .net-5 clean-architecture onion-architecture

我目前正在开发一个使用分层架构(Web/Application/Infrastructure/Domain)的 .NET 5 应用程序。如果我要遵循洋葱/干净架构模式,则依赖项应该只在一个方向流动,例如:
Web -> 应用程序 -> 基础设施 -> 域
我现在发现自己需要从应用层发送几封包含特定前端 URL 的电子邮件。这意味着应用层将了解 Web 层,从而打破了依赖流。
示例用例流程为:

  • 用户发出请求,由 Web 层中的 Controller 处理
  • Controller 调用应用层上的处理程序
  • 应用层使用来自基础设施层的电子邮件服务来发送电子邮件

  • 在第 3 步中,我在应用程序层,但需要 Web URL 来构建电子邮件正文。
    我该如何解决这个问题?

    最佳答案

    我最近在我的组织内解决了这个问题。在我们的例子中,我们有一个公司整体使用的 API“市场”,然后是紧密集成的客户端使用的反向代理,最后是 API 容器的内部负载均衡器。
    这是我的 Web 层和 App 层不应该知道的 3 层 URL 知识(即使在 Web 层它也不应该知道这一点,因为这会使我们的 Web 层承担多个责任,而不仅仅是一个路由器(例如,通过媒体))。
    在基础架构中使用重写器
    这就是 Z. Danev 的 answer是所有关于。这是可行的,但是您必须维护这些层中的每一层的所有规则,并且每次重写都可能会增加开销。此外,根据您返回的数据的复杂性,这些规则可能会变得棘手。
    这是一个有效的解决方案。根据您的组织,这可能是一件容易的事情,也可能是一件困难的事情,因为它由其他团队维护,需要工作票等才能完成工作。
    好吧,如果您不能或不想这样做,那么...
    应用层依赖倒置和模式

    Disclaimer: This solution works great for us, but it does have one drawback: at some level, you have to maintain something that knows about the layers above. So caveat emptor.


    我上面描述的情况与您的问题大致相似,尽管可能更复杂(您可以这样做但简化它)。在不违反您的架构原则的情况下,您需要提供一个接口(interface)(或多个接口(interface)),该接口(interface)可以作为应用程序服务注入(inject)您的应用程序层。
    我们调用我们的ILinkBuilderService并创建了 LinkBuilderService它本身可以通过 DI 容器与单独的 ILinkBuilder 连接起来实现。这些实现中的每一个都可以是 MarketPlaceBuilder , 一个 GatewayBuilder等,并将根据 Chain of Responsibility 进行排列和 Strategy从最外层代理到最内层的模式。
    通过这种方式,构建器检查 Web 上下文( header 、请求等)以确定应由哪一个负责构建链接。您的应用程序层(例如您的电子邮件发件人)只需使用关键数据调用链接构建服务接口(interface),这用于生成面向客户端的 URL,而不会将应用程序层暴露给 Web 上下文。

    Without going into too many details, these builders inspect headers like X-Forwarded-For, custom headers, and other details provided by proxies as the HTTP request hits each endpoint. Chain of Responsibility is key, because it allows the application layer to generate the correct URL no matter at which layer the request originated from.


    那么这如何不破坏单向流呢?
    好吧,您将这些构建器单向下推到您的应用程序层中。从技术上讲,它们确实可以返回到 Web 层以获取上下文,但这是封装的。这没关系,并且不会违反您的架构。这就是依赖倒置的全部内容。

    关于c# - 在分层架构中,应用层如何知道 Web URL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68227301/

    相关文章:

    .net - Microsoft .NET 版本中的 LTS 和 GA 有什么区别?

    c# - 在正在序列化的对象中找不到 TypeLoadExceptionHolder

    c# - ajax调用jquery后如何防止页面重新加载

    c# - 有什么方法可以对 List<T> 的子类进行 JSON.NET 序列化,该子类也具有额外的属性?

    c# - 在 Visual Studio 2008 中将项目更改为 Web 应用程序

    c# - 如何在 C# 中使用 ATD 命令 GSM 调制解调器获取用户响应

    c# - 重用排序逻辑

    c# - 从右到左每 N 个元素分隔字符串

    .net - AutoMapper AssertConfiguration 在编译时?

    f# - 如何让 FSI 在 NET5 下工作并让愚蠢的 stackoverflow 消息 "Title cannot contain ..."闭嘴?