使用 CacheMetadata 公开数据

在执行活动之前,工作流运行时会获取有关活动所需的所有信息,以便维护其执行。 工作流运行时在 CacheMetadata 方法执行期间获取这些信息。 在执行此方法的时候,此方法的默认实现为运行时提供活动公开的所有公共参数、变量和子活动;如果活动需要向运行时提供比这更多的信息(如私有成员或将由该活动安排的活动),可以重写此方法以进行提供。

默认 CacheMetadata 行为

CacheMetadata 所派生活动的 NativeActivity 的默认实现将通过以下方式来处理以下方法类型:

  • InArgument<T>OutArgument<T>InOutArgument<T>(泛型参数):这些参数在运行时作为实参公开,名称和类型与公开的属性名称和类型相同,具有适当的参数方向和一些验证数据。

  • Variable 或其任何子类:这些成员以公共变量的形式向运行时公开。

  • Activity 或其中的任何子类:这些成员作为公共子活动公开给运行时。 通过调用 AddImportedChild 并传入子任务,可以显式实现默认行为。

  • ActivityDelegate 或其中的任何子类:这些成员作为公共委托公开给运行时。

  • ICollection 类型 Variable:集合中的所有元素作为公共变量向运行时公开。

  • ICollection 类型的 Activity:集合中的所有元素都作为公共子活动公开给运行时。

  • ICollection 类型的 ActivityDelegate:集合中的所有元素都作为公共委托公开给运行时。

CacheMetadataActivityCodeActivity 派生的活动 AsyncCodeActivity 也能起到以上的作用,但有以下差异:

  • Activity 派生的类不能安排子活动或委托,所以此类成员作为导入的子活动或委托公开。

  • 派生自 CodeActivityAsyncCodeActivity 的类不支持变量、子级或委托,因此只会公开参数。

重写 CacheMetadata 以向运行时提供信息

以下代码片段演示如何在方法执行 CacheMetadata 期间向活动的元数据添加有关成员的信息。 请注意,调用该方法的基数来缓存有关活动的所有公共数据。

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
    base.CacheMetadata(metadata);
    metadata.AddImplementationChild(this._writeLine);
    metadata.AddVariable(this._myVariable);
    metadata.AddImplementationVariable(this._myImplementationVariable);

    RuntimeArgument argument = new RuntimeArgument("MyArgument", ArgumentDirection.In, typeof(SomeType));
    metadata.Bind(argument, this.SomeName);
    metadata.AddArgument(argument);
}

使用 CacheMetadata 公开实现子活动

若要使用变量将数据传递给要由活动安排的子活动,必须将变量添加为实现变量;公共变量不能以这种方式设置其值。 原因在于,活动将更有可能作为功能的实现(有参数)执行,而不是作为封装类(有属性)执行。 在某些情况下,例如当使用 ScheduleActivity 时,必须显式设置参数,因为计划的活动不像子活动那样能够访问父活动的参数。

以下代码片段演示如何使用 CacheMetadata 将自变量从本机活动传递到计划的活动中。

public sealed class ChildActivity : NativeActivity
{
    public WriteLine _writeLine;
    public InArgument<string> Message { get; set; }
    private Variable<string> MessageVariable { get; set; }
    public ChildActivity()
    {
        MessageVariable = new Variable<string>();
        _writeLine = new WriteLine
        {
            Text = new InArgument<string>(MessageVariable),
        };
    }
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        base.CacheMetadata(metadata);
        metadata.AddImplementationVariable(this.MessageVariable);
        metadata.AddImplementationChild(this._writeLine);
    }
    protected override void Execute(NativeActivityContext context)
    {
        string configuredMessage = context.GetValue(Message);
        context.SetValue(MessageVariable, configuredMessage);
        context.ScheduleActivity(this._writeLine);
    }
}