You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发布Elsa工作流时存储指定活动数据的实现方案咨询

实现Elsa工作流发布时存储特定活动数据的方案

你的中间件方案无法获取活动数据,是因为ASP.NET中间件仅能处理HTTP请求上下文,无法直接访问Elsa工作流的内部模型;且如果工作流是通过内部服务调用发布而非API请求,中间件根本捕获不到操作。以下是基于Elsa自身扩展点的可行方案:

方案一:监听Elsa领域事件

Elsa会在工作流定义创建、更新(发布属于更新操作,生成新版本)时触发领域事件,通过实现事件处理器可以直接获取完整的工作流定义,进而提取活动数据。

1. 编写事件处理器

using Elsa;
using Elsa.Events;
using Elsa.Models;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public class WorkflowActivityDataCollector : IDomainEventHandler<WorkflowDefinitionCreatedEvent>, 
                                           IDomainEventHandler<WorkflowDefinitionUpdatedEvent>
{
    private readonly ICustomActivityDataRepository _activityDataRepo; // 自定义的数据库仓储,用于存储活动数据

    public WorkflowActivityDataCollector(ICustomActivityDataRepository activityDataRepo)
    {
        _activityDataRepo = activityDataRepo;
    }

    public async Task HandleAsync(WorkflowDefinitionCreatedEvent notification, CancellationToken cancellationToken)
    {
        await ExtractAndSaveActivityData(notification.WorkflowDefinition, cancellationToken);
    }

    public async Task HandleAsync(WorkflowDefinitionUpdatedEvent notification, CancellationToken cancellationToken)
    {
        // 仅处理已发布的工作流版本
        if (notification.WorkflowDefinition.VersionStatus == VersionStatus.Published)
            await ExtractAndSaveActivityData(notification.WorkflowDefinition, cancellationToken);
    }

    private async Task ExtractAndSaveActivityData(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken)
    {
        // 筛选出你需要的特定活动(替换成目标活动的类型名称)
        var targetActivities = workflowDefinition.Activities
            .Where(a => a.Type == "Your.Custom.Activity.Type")
            .ToList();

        foreach (var activity in targetActivities)
        {
            // 构建要存储的实体对象
            var activityData = new CustomActivityData
            {
                WorkflowDefinitionId = workflowDefinition.Id,
                WorkflowVersion = workflowDefinition.Version,
                ActivityId = activity.Id,
                ActivityName = activity.Name,
                // 提取活动配置属性(示例:获取名为"TargetProperty"的属性值)
                TargetProperty = activity.Properties.TryGetValue("TargetProperty", out var value) ? value.ToString() : null
            };

            await _activityDataRepo.SaveAsync(activityData, cancellationToken);
        }
    }
}

2. 注册事件处理器

在项目的服务配置中添加:

services.AddScoped<IDomainEventHandler<WorkflowDefinitionCreatedEvent>, WorkflowActivityDataCollector>();
services.AddScoped<IDomainEventHandler<WorkflowDefinitionUpdatedEvent>, WorkflowActivityDataCollector>();

方案二:装饰Elsa的工作流定义存储

通过装饰IWorkflowDefinitionStore接口,在工作流定义保存(发布操作会触发保存)的环节插入自定义逻辑,直接处理工作流模型。

1. 编写装饰器类

using Elsa.Models;
using Elsa.Persistence.Stores;
using System.Threading;
using System.Threading.Tasks;

public class WorkflowDefinitionStoreDecorator : IWorkflowDefinitionStore
{
    private readonly IWorkflowDefinitionStore _innerStore;
    private readonly ICustomActivityDataRepository _activityDataRepo;

    public WorkflowDefinitionStoreDecorator(IWorkflowDefinitionStore innerStore, ICustomActivityDataRepository activityDataRepo)
    {
        _innerStore = innerStore;
        _activityDataRepo = activityDataRepo;
    }

    public async Task<WorkflowDefinition> SaveAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default)
    {
        // 先让Elsa完成工作流定义的保存
        var savedWorkflow = await _innerStore.SaveAsync(workflowDefinition, cancellationToken);

        // 提取并保存特定活动数据,逻辑同方案一
        var targetActivities = savedWorkflow.Activities
            .Where(a => a.Type == "Your.Custom.Activity.Type")
            .ToList();

        foreach (var activity in targetActivities)
        {
            var activityData = new CustomActivityData
            {
                WorkflowDefinitionId = savedWorkflow.Id,
                WorkflowVersion = savedWorkflow.Version,
                ActivityId = activity.Id,
                // 填充其他属性...
            };
            await _activityDataRepo.SaveAsync(activityData, cancellationToken);
        }

        return savedWorkflow;
    }

    // 实现接口的其他方法,直接委托给内部存储实例
    public Task<WorkflowDefinition?> GetByIdAsync(string id, VersionOptions versionOptions, CancellationToken cancellationToken = default)
        => _innerStore.GetByIdAsync(id, versionOptions, cancellationToken);

    public Task DeleteAsync(string id, CancellationToken cancellationToken = default)
        => _innerStore.DeleteAsync(id, cancellationToken);

    // 剩余接口方法同理,全部转发给_innerStore
}

2. 注册装饰器

在服务配置中添加:

services.Decorate<IWorkflowDefinitionStore, WorkflowDefinitionStoreDecorator>();

关键注意事项

  • 活动类型匹配:目标活动的类型名称需准确,自定义活动的类型默认是类的完整命名空间+类名,也可通过活动类上的[Activity(TypeName = "CustomName")]特性自定义。
  • 版本判断:如果只需要处理正式发布的版本,需通过WorkflowDefinition.VersionStatus == VersionStatus.Published过滤。
  • 仓储实现:ICustomActivityDataRepository是你需要自行实现的数据库操作类,用于将活动数据写入目标集合。

内容的提问来源于stack exchange,提问作者Maruful Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:55:29