我正在尝试为承载子活动的WF4创建自定义活动,并将一些参数传递给其子活动。我在下面附上我的活动的简化版本(父母和孩子)
public class Child : CodeActivity
{
public InArgument<Dictionary<string, object>> Data;
protected override void Execute(CodeActivityContext context)
{
Dictionary<string, object> data = Data.Get(context);
//Some operations on the input data
}
}
public class Parent : NativeActivity
{
public InArgument<int> Value1 { get; set; }
public InArgument<string> Value2 { get; set; }
public Child Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
int value1 = Value1.Get(context);
string value2 = Value2.Get(context);
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("value1", value1);
data.Add("value2", value2);
context.SetValue(Body.Data, data);
context.ScheduleActivity(this.Body);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
Body = new Child();
base.CacheMetadata(metadata);
}
}
当工作流程执行到达活动的Execute方法时,Child活动的Data参数为null。
有人可以,请指点我们如何在这两项活动之间传递论据?
答案 0 :(得分:6)
虽然使用额外变量的方法起作用,但是使用某些输入调度子项的“官方”方法是在ActivityAcytion中使用,或者如果您还想要使用ActivityFunc的结果。
我担心代码不会变得更简单或更容易理解,但为了完整起见,我只是决定添加它。
public class Child : CodeActivity<object>
{
public InArgument<Dictionary<string, object>> Data { get; set; }
protected override object Execute(CodeActivityContext context)
{
Dictionary<string, object> data = Data.Get(context);
foreach (var item in data)
{
Console.WriteLine(item);
}
return "Some result";
}
}
public class Parent : NativeActivity<object>
{
public InArgument<int> Value1 { get; set; }
public InArgument<string> Value2 { get; set; }
public ActivityFunc<Dictionary<string, object>, object> Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
int value1 = Value1.Get(context);
string value2 = Value2.Get(context);
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("value1", value1);
data.Add("value2", value2);
context.ScheduleFunc<Dictionary<string, object>, object>(Body, data, ChildCompletionCallback);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
var arg = new DelegateInArgument<Dictionary<string, object>>();
Body = new ActivityFunc<Dictionary<string, object>, object>
{
Argument = arg,
Handler = new Child() { Data = arg }
};
base.CacheMetadata(metadata);
}
private void ChildCompletionCallback(NativeActivityContext context, ActivityInstance completedInstance, object result)
{
//Set the output for the parent activity at the completion of the child activity
this.Result.Set(context, result);
}
}
答案 1 :(得分:2)
我还需要通过父活动从子活动返回结果。为此,我使用ScheduleActivity方法和CompletionCallback参数。我附加了包含out参数集的Parent / Child示例活动,也许有人在某个时候需要它:)
父:
public class Parent : NativeActivity<object>
{
public InArgument<int> Value1 { get; set; }
public InArgument<string> Value2 { get; set; }
private Variable<Dictionary<string, object>> SomeVariable { get; set; } // intermediate variable
private Child Body { get; set; }
public Parent()
{
this.SomeVariable = new Variable<Dictionary<string, object>>("SomeVariable");
this.Body = new Child();
this.Body.Data = new InArgument<Dictionary<string, object>>(SomeVariable);
}
protected override void Execute(NativeActivityContext context)
{
int value1 = Value1.Get(context);
string value2 = Value2.Get(context);
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("value1", value1);
data.Add("value2", value2);
this.SomeVariable.Set(context, data);
context.ScheduleActivity(this.Body, ChildCompletionCallback);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
// needs to be cached as implementation child and variable (Body and SomeVariable must be declared as private then)
metadata.AddImplementationChild(this.Body);
metadata.AddImplementationVariable(SomeVariable);
}
private void ChildCompletionCallback<TResult>(NativeActivityContext context, ActivityInstance completedInstance, TResult result)
{
//Set the output for the parent activity at the completion of the child activity
this.Result.Set(context, result);
}
}
子:
public class Child : CodeActivity<object>
{
public InArgument<Dictionary<string, object>> Data { get; set; }
protected override object Execute(CodeActivityContext context)
{
Dictionary<string, object> data = Data.Get(context);
return "Some result";
}
}
答案 2 :(得分:1)
可能无法直接在Execute方法中设置输入参数的值。必须引入中间变量。 Child.Data参数连接到此变量并且在Parent.Execute方法中。
父:
public class Parent : NativeActivity
{
public InArgument<int> Value1 { get; set; }
public InArgument<string> Value2 { get; set; }
private Variable<Dictionary<string, object>> SomeVariable { get; set; } // intermediate variable
private Child Body { get; set; }
public Parent()
{
this.SomeVariable = new Variable<Dictionary<string, object>>("SomeVariable");
this.Body = new Child();
this.Body.Data = new InArgument<Dictionary<string, object>>(SomeVariable);
}
protected override void Execute(NativeActivityContext context)
{
int value1 = Value1.Get(context);
string value2 = Value2.Get(context);
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("value1", value1);
data.Add("value2", value2);
this.SomeVariable.Set(context, data);
context.ScheduleActivity(this.Body);
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
// needs to be cached as implementation child and variable (Body and SomeVariable must be declared as private then)
metadata.AddImplementationChild(this.Body);
metadata.AddImplementationVariable(SomeVariable);
}
}
子:
public class Child : CodeActivity
{
// Must be declared as property.
public InArgument<Dictionary<string, object>> Data
{
get;
set;
}
protected override void Execute(CodeActivityContext context)
{
var data = this.Data.Get(context);
}
}
这不是一个很好的解决方案但我在WF4中几乎看不到任何好处:)。