我应该从另一个应用服务调用应用服务吗?

Should I be calling an AppService from another AppService?

上下文

目前我在文件和记录管理系统 (DRMS?) 工作。由于一些技术限制,我需要存储一个 "view" 文件和一个 "source" 文件(DOCX 或 XLSX)。查看文件是供用户打印、下载和查看日常使用的 PDF 文件,而源文件是可编辑文件。当用户需要更新文件时,他们将下载源,更新它,并上传一个新的视图文件和相应的源文件。

目前,我无法实施 XL​​SX viewers/editors,并且由于文件的数量,我无法迁移到 ODF 以使用可用的开源查看器。

现在我有两个这样的模型:

public class Document {
    //Other fields
    public virtual List<DigitalFile> Files { get; set; }
}

public class DigitalFile {
    //Other fields
    public virtual Document FileOf { get; set; }
}

Document 模型拥有所有 "business" 数据,而 DigitalFile 模型拥有关于文件本身的数据(路径、url、类型等)

每次创建文档时都会有 1 个视图文件(必需),并且可能有 1 个源文件(某些文档可能无法编辑)。从这里你可以知道,当一个文件是created/updated时,至少有一个数字文件也会是created/updated。

Problem/Question

我将有一个 DocumentAppService 来处理所有 CRUD 操作,但这是我的疑问所在,我应该从另一个 AppService 调用 AppService 吗?我的意思是,当创建一个Document 时,Create 方法是否应该调用DigitalFileAppService 中的另一个Create 方法?还是 DocumentAppService 自己处理一切会更好?

现在,DigitalFile 上的所有 CRUD 操作都与 Document 上的操作相关联,这就是为什么我怀疑是否为文件实施 AppService。

AppServices 不需要与您的实体相关。 AppServices 可以是一个功能需求,这样可以有一个 UploadAppServices,其中将创建两个实体。

我不建议从同一域中的另一个服务调用应用程序服务。应用程序服务旨在从 UI 层调用。它实现审计日志记录、授权、验证......如果您在同一应用层中使用代码,则可能不需要它们。

应用程序服务方法是应用程序的 public 端点。 从另一个应用程序调用服务就像走出您的应用程序并从不同的点进入。如果另一个应用程序服务方法的签名发生更改(因为 UI 中的要求更改),您可能也不想更改应用程序服务方法。

我的建议是将共享代码分离到另一个 class(可能是域服务)并从两个应用程序服务中使用。

理想情况下,AppService 应该调用另一个 AppService。

应用程序服务应将数据传输对象 (DTO) 映射到域对象(实体),应用应用程序逻辑并将它们传递给相应的域管理器以实现持久性。

注入多个管理器是完全没问题的,尤其是在映射配置正确的情况下。在可能的情况下,应用程序服务不应依赖于另一个应用程序服务。


实际上,应用程序服务可以通过接受嵌套的 "secondary" DTO 来提供便利(以及由于较少的服务器调用而带来的速度)。这些 DTO 可能涉及单独的应用程序逻辑。

干净地执行此操作的一种方法是在依赖项应用程序服务中创建 internal 方法,例如CreateInternal 用于 Create 方法。 internal 方法不会转换为动态 Web API 方法,避免拦截器的授权和验证开销

此外,如果您想直接从 MVC 控制器调用这些方法,ABP 框架提供 [RemoteService(IsEnabled = false)] 属性 — 因此这些方法需要 public.