WF。 NativeActivity内的C#表达式 [英] WF. C# expressions inside of NativeActivity
问题描述
我正在尝试在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屋!