【问题标题】:Blazor WebAssembly with Clean Architecture具有简洁架构的 Blazor WebAssembly
【发布时间】:2020-05-20 06:21:24
【问题描述】:

我正在使用 Blazor WebAssembly 进行概念验证项目。该项目已经有一个 React 前端,我希望在 Blazor 中复制它。

我的解决方案中有以下项目:

  • 域 - 包含实体且不引用任何其他层
  • 应用程序 - 引用域并包含 DTO, 命令/查询(使用 MediatR/Dapper),验证器(使用 FluidValidation) 和后续层实现的接口
  • Persistence – 引用应用程序并使用 EF Core 存储 数据库中的领域模型
  • API - 一个 Web API,它使用 DI 注册所有内容并公开 通过控制器从应用层发出命令/查询
  • React 前端 - 使用 AJAX 与 API 对话

我想在 Blazor WebAssembly 项目中引用应用程序层,以便我可以重用针对 DTO 存在的验证规则。是否有可能有人单步执行浏览器中的代码并从命令/查询中提取敏感信息,例如连接字符串?

例如,一个简单的查询可能看起来像这样,单步执行代码将允许检查IDbConnection

public class PayCategoryListQueryHandler
    : IRequestHandler<PayCategoryListQuery, PayCategoryListQueryVm>
  {
    private readonly IDbConnection _connection;

    public PayCategoryListQueryHandler(IDbConnection connection)
    {
      _connection = connection;
    }

    public async Task<PayCategoryListQueryVm> Handle(PayCategoryListQuery query, CancellationToken cancellationToken)
    {
      {
        var viewModel = new PayCategoryListQueryVm();

        viewModel.AddRange(
          await _connection.QueryAsync<PayCategoryListItemDto>(
            "SELECT Id, Description, MakeAttendedTimeZero, IsOffSite, IsVisibleToClient FROM PayCategory ORDER BY Description"));

        return viewModel;
      }
    }
  }

我是否需要将 DTO 及其验证提取到不包含任何数据库访问代码的单独层以防止连接字符串泄露?

澄清

为了尝试澄清问题,我想尝试更好地解释我的情况。

我当前的应用程序使用 React 前端,Formik 和 Yup 提供验证。这意味着每次对验证规则进行更改时,我都需要在两个地方反映它——应用程序层和 React 应用程序。我希望迁移到 Blazor 可以减少重复,只需在应用层维护验证规则。

我目前使用的架构基于NorthwindTraders 示例应用程序。

使用该示例,CreateCustomerCommand 使用 CreateCustomerCommandValidator,它将通过 CustomersController 响应 POST 请求。为了在 Blazor WebAssembly 中将其用于 客户端 验证,我目前需要引用应用程序层。

在这种情况下,应将所有命令(不是命令处理程序)和验证器移动到单独的项目中,然后 Blazor 可以引用该项目。命令处理程序可以保留在应用程序层中,因此删除任何数据库访问代码。

【问题讨论】:

  • 我不希望客户端出现这种情况。 PayCategoryListQueryHandler 位于应用程序层中,这也是 DTO 和验证所在的位置。使用 React 时,它会转到 AJAX->API->Application,所以没有问题。使用 Blazor(以便我可以重用验证)我引用了问题出现的应用层。
  • 实际上你不应该在 Blazor wasm 应用程序中引用你的应用程序层,因为你没有在你的 React 前端这样做。但是调用你的 API。您可以(我鼓励您)参考您的域层
  • 将您的 DTO 从您的应用程序层中分离出来,将它们放入共享的 - 或您选择的任何名称 - Blazor 设置的项目中,并从客户端和应用程序层引用它。更好的是,引用域并且没有 DTO。
  • @Rich Bryant - 抱歉,我正在更新帖子,但没有看到您的评论。 DTO 主要用于删除 EF 原生属性等。我认为您将它们移动到另一个项目的建议可能是要走的路。
  • @Newm,您最终为此使用了什么解决方案?我觉得这应该是一个很常见的问题,但你的问题似乎基本上是互联网上唯一的一个。

标签: blazor blazor-server-side


【解决方案1】:

创建一个名为 MyProject.Domain.Shared 的新 dotnet.standard 项目。你把所有的通信(poco-)类都放在那里。

Shared-Project 由您的Domain-ProjectApplication-LayerClient-Layer 使用. Domain-ProjectApplication-LayerPersistence-Layer 使用。

在您放置的 Shared-Project 中:

  • DTO
  • 请求
  • 回复
  • 验证器

在您放置的 Application-Project 中:

  • 请求处理程序
  • 响应处理程序

在您放置的 Domain-Project 中:

  • 域对象
  • 存储库接口
  • 处理请求并产生响应的处理程序)

【讨论】:

  • 在域项目中拥有请求处理程序会不会违反干净/洋葱架构,因为它需要依赖基础设施等?
  • 是的,你是对的。如果您以严格的方式实现干净的架构,则应始终将请求、DTO 等映射到域项目中而不是被引用。在现实世界中,我认为分享该课​​程可以节省时间。但当然,每个专业人士都有一个反对者。所以你必须根据每个项目来决定。
【解决方案2】:

为了保持表示层与应用层分离,即使您使用 Blazor,也不应从表示层的任何位置直接引用某些应用层的代码。相反,调用 API 端点的方式与使用 React 前端的方式相同。

另外,正如 cmets 中其他人所说,您应该将 dto-poco 类提取到另一个项目中,并引用这个。

【讨论】:

    猜你喜欢
    • 2021-04-10
    • 2020-07-24
    • 2020-08-19
    • 2020-06-26
    • 2018-04-24
    • 2021-01-23
    • 2021-02-13
    • 2021-02-08
    • 2020-06-28
    相关资源
    最近更新 更多