【问题标题】:WF. C# expressions inside of NativeActivityWF。 NativeActivity 中的 C# 表达式
【发布时间】:2013-04-24 13:43:51
【问题描述】:

我正在尝试在 NativeActivity 中使用自定义 c# 表达式

它适用于简单的表达式,如 Condition = new CSharpValue("1 == 1")

它不适用于这样的表达式Condition = new CSharpValue("Address == null")

由于表达式编译错误“当前上下文中不存在名称 'xxxxx'”,我无法在表达式中引用活动的变量或 InArgument

工作代码

var act = new ExecuteIfTrue
{
    Condition = new CSharpValue<Boolean>("1 == 1"),
    Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
    Body = new WriteLine { Text = "Rest!" }
};

CompileCSharpExpressions<MailAddress>(act);
WorkflowInvoker.Invoke(act);

非工作代码(指 NativeActivity 的 InArgument)

var act = new ExecuteIfTrue
{
    Condition = new CSharpValue<Boolean>("Address.Email == null"),
    //Condition = new CSharpValue<Boolean>("MailAddressVar == null"),
    Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
    Body = new WriteLine { Text = "Rest!" }
};

CompileCSharpExpressions<MailAddress>(act);
WorkflowInvoker.Invoke(act);

NativeActivity

public class ExecuteIfTrue : NativeActivity
{
    [RequiredArgument]
    public InArgument<bool> Condition { get; set; }

    [RequiredArgument]
    public InArgument<MailAddress> Address { get; set; }

    public Variable<MailAddress> MailAddressVar;

    public Activity Body { get; set; }

    public ExecuteIfTrue()
    {
        MailAddressVar = new Variable<MailAddress> { Default = null };
    }

    protected override void Execute(NativeActivityContext context)
    {
        if (context.GetValue(this.Condition) && this.Body != null)
            context.ScheduleActivity(this.Body);
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddImplementationVariable(MailAddressVar);
        base.CacheMetadata(metadata);
    }
}


public class MailAddress
{
    public String Email { get; set; }
    public String DisplayName { get; set; }
}

辅助方法

public static void CompileCSharpExpressions<T>(Activity activity)
{
    var impl = new AttachableMemberIdentifier(typeof(TextExpression), "NamespacesForImplementation");
    var namespaces = new List<string> { typeof(T).Namespace };
    TextExpression.SetReferencesForImplementation(activity, new AssemblyReference { Assembly = typeof(T).Assembly });
    AttachablePropertyServices.SetProperty(activity, impl, namespaces);

    var activityName = activity.GetType().ToString();
    var activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
    var activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());

    var settings = new TextExpressionCompilerSettings
    {
        Activity = activity,
        Language = "C#",
        ActivityName = activityType,
        ActivityNamespace = activityNamespace,
        RootNamespace = null,
        GenerateAsPartialClass = false,
        AlwaysGenerateSource = true,
        ForImplementation = false
    };

    var results = new TextExpressionCompiler(settings).Compile();

    if (results.HasErrors)
    {
        throw new Exception("Compilation failed.");
    }

    var compiledExpressionRoot = Activator.CreateInstance(results.ResultType, new object[] { activity }) as ICompiledExpressionRoot;
    CompiledExpressionInvoker.SetCompiledExpressionRoot(activity, compiledExpressionRoot);
}

【问题讨论】:

  • 您期望发生的是工作流运行时以某种方式理解字符串“地址”指的是 InArgument 的名称。我假设您希望能够在运行时执行一些外部代码。为此,我会考虑传入 Activity 或 ActivityDelegate 作为参数。

标签: expression workflow-foundation


【解决方案1】:

错误非常明显;您的表达式在范围内没有变量 MailAddressVar

原因是您需要将变量传递给表达式。 ExecuteIfTrue 活动没有 variables 参数。

试试这样的:

Variable<string> mailAddressVar = new Variable<string>(name: "MailAddressVar", defaultValue: null);

Activity seq = new Sequence
{
    Variables = { mailAddressVar },
    Activities = 
    {
        new ExecuteIfTrue
        {       
            //Condition = new CSharpValue<Boolean>("Address.Email == null"),
            Condition = new CSharpValue<Boolean>("MailAddressVar == null"),
            Address = new InArgument<MailAddress>(ctx => new MailAddress { DisplayName = "TestDisplayName" }),
            Body = new WriteLine { Text = "Rest!" }
        }
    }
};

ExecuteIfTrue.CompileCSharpExpressions<MailAddress>(seq);
WorkflowInvoker.Invoke(seq);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 2017-03-27
    • 2018-09-23
    • 1970-01-01
    • 2017-10-02
    • 2011-01-26
    相关资源
    最近更新 更多