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

如何在EventFlow的EventEntity中添加Metadata

给EventFlow事件添加自定义Metadata的实现方法

1. 在事件类中直接添加元数据

你可以在事件的构造函数里直接往Metadata集合添加自定义字段,或者重写GetMetadata方法统一注入元数据:

public class OrderCreatedEvent : AggregateEvent<OrderAggregate, OrderId>
{
    public string OrderNumber { get; }

    public OrderCreatedEvent(string orderNumber)
    {
        OrderNumber = orderNumber;
        // 直接添加自定义元数据
        Metadata.Add("OrderSource", "WebPortal");
        Metadata.Add("OperationType", "Create");
    }

    // 或者重写方法实现统一元数据注入
    public override IReadOnlyDictionary<string, string> GetMetadata()
    {
        var baseMetadata = new Dictionary<string, string>(base.GetMetadata());
        baseMetadata.Add("CustomKey", "FixedValue");
        return baseMetadata;
    }
}

2. 全局元数据钩子(批量给所有事件加元数据)

如果需要给所有事件统一添加元数据(比如当前用户ID、请求追踪ID),可以实现IMetadataHook接口并注册到EventFlow配置中:

定义钩子类

public class GlobalMetadataHook : IMetadataHook
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public GlobalMetadataHook(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public Task<IReadOnlyDictionary<string, string>> OnAddMetadataAsync(
        object eventObject,
        IReadOnlyDictionary<string, string> metadata,
        CancellationToken cancellationToken)
    {
        var customMetadata = new Dictionary<string, string>(metadata);
        
        // 从HttpContext获取当前用户ID
        var userId = _httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (!string.IsNullOrEmpty(userId))
        {
            customMetadata["InitiatedByUserId"] = userId;
        }
        
        // 添加请求追踪ID
        customMetadata["RequestTraceId"] = _httpContextAccessor.HttpContext?.TraceIdentifier ?? Guid.NewGuid().ToString();

        return Task.FromResult<IReadOnlyDictionary<string, string>>(customMetadata);
    }
}

注册钩子到EventFlow

var eventFlowResolver = EventFlowOptions.New
    .AddMetadataHook<GlobalMetadataHook>()
    // 其他聚合、命令等配置...
    .CreateResolver();

3. 在命令处理中按需添加元数据

如果需要根据命令上下文动态添加元数据,可以在命令处理器中通过EventMetadataBuilder传递:

public class CreateOrderCommandHandler : CommandHandler<OrderAggregate, OrderId, CreateOrderCommand>
{
    public override Task ExecuteAsync(
        OrderAggregate aggregate,
        CreateOrderCommand command,
        CancellationToken cancellationToken)
    {
        var metadataBuilder = new EventMetadataBuilder()
            .Add("CommandId", command.CommandId.ToString())
            .Add("RequestedBy", command.Username);
        
        // 传递元数据构建器到聚合根方法
        aggregate.CreateOrder(command.OrderNumber, metadataBuilder);
        return Task.CompletedTask;
    }
}

聚合根中应用带元数据的事件

public class OrderAggregate : AggregateRoot<OrderAggregate, OrderId>
{
    public void CreateOrder(string orderNumber, IEventMetadataBuilder metadataBuilder)
    {
        var orderCreatedEvent = new OrderCreatedEvent(orderNumber);
        // 应用事件时传入自定义元数据
        Apply(orderCreatedEvent, metadataBuilder);
    }
}

验证效果

事件存储到EventEntity表后,查看Metadata字段的JSON内容,就能看到你添加的自定义键值对已被注入。

内容的提问来源于stack exchange,提问作者Maxime Dousselaere

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:06:31