開源的 .NET 工作流引擎 Elsa 開源
前言
微軟的Workflow Foundation基于.NET Framework,并且沒有向.NET Core遷移的計劃。
我們的很多項目使用了工作流引擎,這些項目向.NET Core以及更高版本遷移時遇到了不少問題,一直在尋找/開發(fā)適合的工作流引擎。
找到一些開源的項目,可以解決一些問題,還有些項目不是基于.NET生態(tài)的,但我希望能有一個長期穩(wěn)定的基于.NET生態(tài)的項目,能夠滿足多種場景,可以替換原來的Workflow Foundation。
特性
1、同時支持編程工作流定義和配置工作流定義,最好有圖形化的管理工具。
2、支持長期工作流。
3、支持有限狀態(tài)機(jī)類型的工作流定義。
4、工作流引擎可以集成在應(yīng)用中,也可以獨立部署為工作流服務(wù)器,采用Web API的方式調(diào)用。
在我們跟蹤的工作流相關(guān)項目中,Elsa一直在穩(wěn)步發(fā)展,最新的版本(2.9)已經(jīng)基本可以滿足我們的上述要求了,在以后的版本也會增加對有限狀態(tài)機(jī)的支持。
這里簡單介紹一下如何創(chuàng)建工作流服務(wù)器和圖形化的工作流配置管理應(yīng)用。
正文
首先,使用Visual Studio 2022創(chuàng)建一個空的ASP.NET Core Web應(yīng)用,名稱為MyElsaServer。
項目創(chuàng)建完成后,使用NuGet包管理器,安裝如下程序包:
Install-Package?Elsa
Install-Package?Elsa.Activities.Http
Install-Package?Elsa.Persistence.EntityFramework.Sqlite
Install-Package?Elsa.Server.Api
然后,修改項目的Properties/launchSettings.json,去掉通過IIS Express啟動的選項:
{
??"profiles":?{
????"MyElsaServer":?{
??????"commandName":?"Project",
??????"dotnetRunMessages":?true,
??????"launchBrowser":?true,
??????"applicationUrl":?"http://localhost:5298",
??????"environmentVariables":?{
????????"ASPNETCORE_ENVIRONMENT":?"Development"
??????}
????}
??}
}
最后,修改Program.cs:
using?Elsa.Persistence.EntityFramework.Core.Extensions;
using?Elsa.Persistence.EntityFramework.Sqlite;
var?builder?=?WebApplication.CreateBuilder(args);
var?elsaSection?=?builder.Configuration.GetSection("Elsa");
//?Elsa?services.
builder.Services
????.AddElsa(elsa?=>?elsa
????????.UseEntityFrameworkPersistence(ef?=>?ef.UseSqlite())
????????.AddConsoleActivities()
????????.AddHttpActivities(elsaSection.GetSection("Server").Bind)
????????.AddJavaScriptActivities()
????);
//?Elsa?API?endpoints.
builder.Services.AddElsaApiEndpoints();
//?Allow?arbitrary?client?browser?apps?to?access?the?API.
//?In?a?production?environment,?make?sure?to?allow?only?origins?you?trust.
builder.Services.AddCors(cors?=>?cors.AddDefaultPolicy(policy?=>?policy
????.AllowAnyHeader()
????.AllowAnyMethod()
????.AllowAnyOrigin()
????.WithExposedHeaders("Content-Disposition"))
);
var?app?=?builder.Build();
app
????.UseCors()
????.UseHttpActivities()
????.UseRouting()
????.UseEndpoints(endpoints?=>
?????{
???????//?Elsa?API?Endpoints?are?implemented?as?regular?ASP.NET?Core?API?controllers.
???????endpoints.MapControllers();
?????})
????.UseWelcomePage();
app.Run();
最后,在appSettings.json中增加服務(wù)器地址的定義:
??"Elsa":?{
????"Http":?{
??????"BaseUrl":?"http://localhost:5298"
????}
??}
啟動項目,會出現(xiàn)歡迎界面:

服務(wù)器可以運行了,但還沒有定義工作流,現(xiàn)在我們創(chuàng)建圖形化的工作流定義和管理應(yīng)用,向工作流服務(wù)器發(fā)布工作流,并查看工作流的執(zhí)行情況。
在解決方案中增加一個新的ASP.NET Core Web空項目,命名為MyElsaDashboard,修改Properties/launchSettings.json,將項目改為自啟動:
{
??"profiles":?{
????"MyElsaDashboard":?{
??????"commandName":?"Project",
??????"dotnetRunMessages":?true,
??????"launchBrowser":?true,
??????"applicationUrl":?"http://localhost:5060",
??????"environmentVariables":?{
????????"ASPNETCORE_ENVIRONMENT":?"Development"
??????}
????}
??}
}
在項目中添加如下程序包:
Install-Package Elsa.Designer.Components.Web修改Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints => { endpoints.MapFallbackToPage("/_Host"); });
app.Run();然后在項目中創(chuàng)建Pages文件夾,在文件夾中添加兩個Razepage頁面,名稱為_ViewImports.cshtml和_Host.cshtml,_ViewImports的內(nèi)容如下:
@?addTagHelper?*,?Microsoft?.AspNetCore.Mvc.TagHelpers
_Host.cshtml的內(nèi)容如下:
@page?"/"
html>
<html?lang="en">
<head>
????<meta?charset="utf-8"/>
????<meta?name="viewport"?content="width=device-width,?initial-scale=1.0"/>
????<title>Elsa?Workflowstitle>
????<link?rel="icon"?type="image/png"?sizes="32x32"?href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-32x32.png">
????<link?rel="icon"?type="image/png"?sizes="16x16"?href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-16x16.png">
????<link?rel="stylesheet"?href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/fonts/inter/inter.css">
????<link?rel="stylesheet"?href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.css">
????<script?src="/_content/Elsa.Designer.Components.Web/monaco-editor/min/vs/loader.js">script>
????<script?type="module"?src="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.esm.js">script>
head>
<body>
<elsa-studio-root?server-url="http://localhost:5298"?monaco-lib-path="_content/Elsa.Designer.Components.Web/monaco-editor/min">
????<elsa-studio-dashboard>elsa-studio-dashboard>
elsa-studio-root>
body>
html>
請注意上面的server-url屬性,這里指向我們前面創(chuàng)建的Elsa服務(wù)器地址。
現(xiàn)在我們修改解決方案的啟動項目,設(shè)置為兩個項目同時啟動:

在Visual Studio中執(zhí)行啟動,管理界面如下:

選擇Workflow Definitions進(jìn)入流程定義管理界面,點擊“Create Workflow”創(chuàng)建新的流程:

點擊Start,然后選擇Http->Http EndPoint,定義流程的入口url:

設(shè)置完成后按Save保存,可以看到多個一個環(huán)節(jié),在這個環(huán)節(jié)下點擊“+”圖標(biāo)可以繼續(xù)添加環(huán)節(jié),這里選擇HttpResponse:

在Advanced選擇卡中,選擇Status Code為Ok,添加完成后,流程如下:

流程定義完成了,點擊Publish發(fā)布流程到流程服務(wù)器。
流程發(fā)布后,可以在流程服務(wù)器執(zhí)行流程。
我們在瀏覽器訪問http://localhost:5298/hello-world,可以看到流程執(zhí)行的結(jié)果:

回到流程管理應(yīng)用,選擇Workflow Instances,可以看到剛剛執(zhí)行完成的流程實例:

點擊流程Id,可以查看流程執(zhí)行的詳細(xì)過程:

到此,我們完成了工作流服務(wù)和管理應(yīng)用的創(chuàng)建。
示例代碼
Github地址:https://github.com/zhenl/MyElsa
