wf4活动只能访问自己的实现变量

时间:2015-06-03 10:00:02

标签: c# workflow-foundation-4

我有一个带变量的活动(它是C#表达式),但无法读取它们的值。

    public Collection<Variable> Variables { get; } = new Collection<Variable>();

    protected override void DoExecute(NativeActivityContext context)
    {
        var x = Variables.FirstOrDefault(...).Get(context);
    }

导致

Activity '1.1: MyActivity' cannot access this variable 
because it is declared at the scope of activity '1.1: MyActivity'.  
An activity can only access its own implementation variables.

我试图通过cachemetadata

公开它们
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.SetImplementationVariablesCollection(Variables);
    }

导致

Exception <System.NotSupportedException: 
Expression Activity type 'CSharpValue`1' requires compilation in order to run.  
Please ensure that the workflow has been compiled.

我的变量是c#表达式,用

编译
var wwfActivity = ActivityXamlServices.Load(xamlReader, new ActivityXamlServicesSettings {CompileExpressions = true});

enter image description here

2 个答案:

答案 0 :(得分:1)

我能够用

破解它
var var = context.DataContext.GetProperties()["variableName"];
var value = var.GetValue(context.DataContext) as Whatever;

没有覆盖CacheMetadata方法,但感觉很奇怪;

答案 1 :(得分:0)

我认为如果你在一个while循环中,中间有一个计数器,并试图访问像“Number”+ i.ToString这样的变量,你将得不到正确的答案。它不会评估i.ToString。

using System; 
using System.ComponentModel; 
using System.IO;
using System.Runtime; 
using System.Activities.Validation;
using System.Collections.Generic;
using System.Windows.Markup;
using System.Collections.ObjectModel;
using System.Activities; 

namespace WorkflowConsoleApplication2
{

public sealed class CodeActivity1 : CodeActivity
{
    // Define an activity input argument of type string
    [DefaultValue(null)]
    public InArgument<string> Test
    {
        get;
        set;
    }

    protected override void CacheMetadata(CodeActivityMetadata metadata)
    {
        RuntimeArgument textArgument = new RuntimeArgument("Test",    typeof(string), ArgumentDirection.In);
        metadata.Bind(this.Test, textArgument);


        metadata.SetArgumentsCollection(
        new Collection<RuntimeArgument> 
        {
            textArgument,
        });
    }

    // If your activity returns a value, derive from CodeActivity<TResult>
    // and return the value from the Execute method.
    protected override void Execute(CodeActivityContext context)
    {
        Console.WriteLine(this.Test.Get(context)); 
    }
 }

您需要将该RuntimeArgument添加到ArgumentCollection中,如上所示。

我从我的回答问题中得到了这个:While activity in WF 4 rehosted designer