【问题标题】:Should I be calling an AppService from another AppService?我应该从另一个应用服务调用应用服务吗?
【发布时间】:2018-03-21 01:43:15
【问题描述】:

上下文

目前我在文档和记录管理系统 (DRMS?) 中工作。由于一些技术限制,我需要存储一个“视图”文件和一个“源”文件(DOCX 或 XLSX)。查看文件是供用户打印、下载和查看日常使用情况的 PDF 文件,而源文件是可编辑文件。当用户需要更新文件时,他们会下载源代码,更新它,然后上传一个新的视图文件和对应的源文件。

目前我无法实现 XLSX 查看器/编辑器,并且由于文件数量的原因,我无法迁移到 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 模型包含所有“业务”数据,而 DigitalFile 模型包含有关文件本身的数据(路径、url、类型等)

每次创建文档时都会有 1 个视图文件(必需),并且可能有 1 个源文件(某些文档可能无法编辑)。由此您可以知道,当一个文档被创建/更新时,至少会创建/更新一个数字文件。

问题/疑问

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

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

【问题讨论】:

    标签: c# aspnetboilerplate


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我在看到这个之前就开始写我的答案,我很高兴我有类似的理解:)
      • 我以为我已经阅读了有关 ABP 的所有文档。在深夜尝试解决问题后,在阅读了答案后,我再次前往“文档”寻找域服务。看看这正是我需要的例子。我仍然不知道我是否应该为 DigitalFile 提供应用程序服务,因为它们不会与 Document 分开创建,但与此同时我还有一些工作要做。谢谢
      【解决方案3】:

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

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

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


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

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

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

      【讨论】:

      • 感谢您的意见,虽然我接受了 hikalkan 的回答,但我会在开发时考虑这些信息。
      • 是的,没问题:)
      猜你喜欢
      • 2011-02-07
      • 2019-05-03
      • 2019-12-24
      • 2011-05-06
      • 2010-11-24
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多