WF。 NativeActivity内的C#表达式 [英] WF. C# expressions inside of NativeActivity

查看:246
本文介绍了WF。 NativeActivity内的C#表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

它可以像简单的表达式一样工作,如 Condition = new CSharpValue(1 == 1 )



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



由于表达式编译错误,我无法引用表达式中的活动的Variable或InArgument当前上下文中xxxxx不存在



工作代码

  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) p>

  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>条件{get;组; }

[RequiredArgument]
public InArgument< MailAddress>地址{get;组; }

public Variable< MailAddress> MailAddressVar;

public Activity Body {get;组; }

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

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

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


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

助手方法

  public static void CompileCSharpExpressions< T>(活动活动)
{
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);
}


解决方案

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



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



而是尝试这样:

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

活动seq = new序列
{
变量= {mailAddressVar},
活动=
{
new ExecuteIfTrue
{
// Condition = new CSharpValue< Boolean>(Address.Email == null),
Condition = new CSharpValue< Boolean>(MailAddressVar == null),
Address =新的InArgument< MailAddress>(ctx => new MailAddress {DisplayName =TestDisplayName}),
Body = new WriteLine {Text =Rest! }
}
}
};

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


I am trying to use custom c# expression inside of NativeActivity

It works fine with simple expression like Condition = new CSharpValue("1 == 1")

It doesn't work with such expressions Condition = new CSharpValue("Address == null")

I cannot refer to the activity's Variable or InArgument in the expression due to expression compilation error "The name 'xxxxx' does not exist in the current context"

Working code

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);

Non-Working code (refers to the InArgument of NativeActivity)

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; }
}

Helper method

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);
}

解决方案

The error is pretty explicit; your expression does not have the variable MailAddressVar in scope.

The reason being is you need to pass the variable into the expression. The ExecuteIfTrue activity does not have a variables parameter.

Instead try something like this:

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);

这篇关于WF。 NativeActivity内的C#表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆