本系列介绍了由 Elsa 工作流引擎驱动的用户界面的实现。
几个不同的步骤将导致全面有效的实施。 此实现可能无法为您提供满足您的特定需求的灵丹妙药。 尽管如此,它仍将提供对各种选项的见解。 本系列并不是详尽的分步实施指南。 会有代码片段,但更多的是关于概念以及它们可能对应用程序设置产生的影响。
对于那些不了解 Elsa 的人来说,Elsa 是一个开源的 .NET Standard 库和工具套件,使开发人员能够实现长时间运行的工作流程。 Elsa 的核心理念是连接称为活动的小型可执行单元。 这些小型单元使您能够协调文档审批、客户引导和订单履行等业务流程。
这是我们要做的:
- 创建一个单元,该单元暂停工作流程的执行,直到收到信号和其他数据。 这将是用户任务活动的基础。
- 创建一个可以收集所有等待执行的用户任务的 UI。
- 将信号从 UI 发送到引擎以继续执行。
- 扩展用户任务,使其能够描述所请求的数据。
- 通过等待引擎信号而不是轮询引擎,使 UI 具有反应性。
因为涉及大量的代码编辑,所以我们将在不同的部分中完成所有这些工作:
- 第 1 部分 — 设置项目
- 第 2 部分 — 创建用户任务活动
- 第 3 部分 — 使用数据扩展用户任务
- 第 4 部分 — 使用户界面由工作流程引导
- 第 5 部分 — 使用通知更新用户界面
- 第 6 部分 — 在工作流程开始时使用用户任务
本系列中使用的技术是
- Elsa 2.10.467
- Blazor App
- C#
- SignalR
尽管 Blazor 用于构建用户界面,但相同的概念也适用于其他 UI 解决方案。
完整的解决方案可以在这里找到,包括每个部分的一个分支。
关键概念
在我们进行实际工作之前,简要介绍一下 Elsa 工作流程执行上下文中的不同元素可能会很方便。
阻止活动
在 Elsa 中,阻塞活动可用于触发工作流程的启动或恢复暂停的活动。
ELSA 2 中的工作流以每个分支执行的方式执行,这意味着当工作流分成多个执行分支时,引擎将执行每个分支,直到到达工作流末尾或遇到阻塞活动。 阻止活动不会停止整个工作流程,而只会停止特定分支。
书签
书签是一个小信息,指示等待引擎启动或恢复的工作流实例。
您可以将书签视为您停止阅读本书的位置以及暂停后继续阅读的位置的指示器。
控制器
控制器提供端点来扩展引擎以获得更多交互入口点。
控制器允许与引擎交互。 Elsa 的开放式架构可以扩展附加功能。 一种是在引擎中的 API 范围内添加控制器。
详细信息可以在这里找到:编写阻塞活动·ELSA (elsa-workflows.github.io)
如果您阅读本文,您会发现 Elsa 已经有一个用户任务活动。 然而,本系列创建了一个新活动,将该活动与现有活动区分开来,因为新活动是专门针对 UI 用户任务的。 除此之外,它还展示了如何创建活动。
第 1 部分 — 设置项目。
该解决方案由 2 个项目组成:Blazor 应用程序和 Elsa 引擎。 只需创建一个解决方案并添加项目即可。 对于 Elsa 引擎,您还可以选择安装仪表板。 它提供了对工作流程执行的易于理解的见解。 此外,它还提供选项来查看工作流实例是否保存 UI 提供的值。
Elsa 服务器项目是引擎和 Blazor 应用程序的简单实现。 设置引擎的教程不会涵盖使用 .NET 6 时的所有细节。
带有 Elsa 仪表板 + Elsa 服务器 API 端点的 ASP.NET Core 服务器 · ELSA (elsa-workflows.github.io)
.Net6 设置所需的调整(包括 swagger 基本实现)主要在启动类中。
using Elsa;
using Elsa.Activities.Http.Options;
using Elsa.Persistence.EntityFramework.Core.Extensions;
using Elsa.Persistence.EntityFramework.Sqlite;
namespace ElsaEngine
{
public class Startup
{
public IConfiguration configRoot
{
get;
}
public Startup(IConfiguration configuration)
{
configRoot = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
var elsaServerUrl = configRoot.GetValue<string>("Elsa:Server:BaseUrl");
// Elsa services.
services
.AddElsa(elsa => elsa
.UseEntityFrameworkPersistence(ef => ef.UseSqlite())
.AddConsoleActivities()
.AddHttpActivities(a =>
{
HttpActivityOptions httpActivityOptions = new()
{ BasePath = "", BaseUrl = new Uri(elsaServerUrl) };
})
.AddQuartzTemporalActivities()
.AddWorkflowsFrom<Startup>()
); ;
// Elsa API endpoints.
services.AddElsaApiEndpoints()
.AddElsaSwagger();
// For Dashboard.
services.AddRazorPages();
}
public void Configure(WebApplication app, IWebHostEnvironment env)
{
app
.UseStaticFiles() // For Dashboard.
.UseHttpActivities()
.UseRouting()
.UseSwagger()
.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Elsa UI API V1"); })
.UseEndpoints(endpoints =>
{
// Elsa API Endpoints are implemented as regular ASP.NET Core API controllers.
endpoints.MapControllers();
// For Dashboard.
endpoints.MapFallbackToPage("/_Host");
});
app.Run();
}
}
}
Blazor 应用程序是典型安装。
在本系列的以下部分中,该应用程序通过与引擎交互的逻辑进行了扩展。 重要的是要知道设计不会参考引擎。 因此,在某些情况下,DTO 对象是在两个项目中定义的。
该项目的目标是拥有一个驱动独立 UI 应用程序的引擎。 反过来,Elsa 引擎不知道 UI 应用程序的详细信息。 相反,Elsa 引擎将提供有关预期数据类型的详细信息。 由 UI 应用程序选择使用该信息或实现它。
安装的最终结果可以在这里找到:
ElsaDrivenUI