2010-12-02 83 views
2

如何在.NET 4下的Windows Workflow Foundation活动中从父范围动态设置变量的值?从WF 4活动动态设置外部范围变量

失败(上一个工作流程,序列有一个名为测试一个int变量上的一系列活动下降)的尝试:

public sealed class CodeActivity1 : NativeActivity 
{ 
    protected override void CacheMetadata(NativeActivityMetadata metadata) 
    { 
     _locationReferences = 
      metadata.Environment.GetLocationReferences().ToList(); 

     base.CacheMetadata(metadata); 
    } 

    protected override void Execute(NativeActivityContext context) 
    { 
     LocationReference locationReference = 
      _locationReferences.Find(
       x => x.Name == "Test" && x.Type == typeof (int)); 

     if (locationReference != null) 
     { 
      Console.WriteLine(
       locationReference.Name + " " + locationReference.Type); 

      // Blows up here. 
      Location location = locationReference.GetLocation(context); 
      location.Value = 5; 
     } 
    } 

    private List<LocationReference> _locationReferences; 
} 

这导致:

System.InvalidOperationException了 用户代码未处理
消息=活动“1.2:CodeActivity1” 无法访问此变量,因为它在活动范围处声明了'1.1:序列'。一个活动只能访问 变量。

它找到了变量;它只是无法获得或设定其价值。

直到运行时才能知道变量名称(上例中的“测试”)。

回答

6

处理此问题的常规方法是定义OutArgument,并在工作流设计器中将OutArgument绑定到变量。在这个活动中,你只能使用参数。使用NativeActivity会为您提供名为Result的OutArgument,但只需添加OUtArgument的属性就可以了。

另一个好处是,你不需要知道“魔术”变量名来存储结果。

更新,因为在下面的评论的代码不可读。

尝试添加以下只是行前炸毁:

var pi = context.GetType().GetProperty("AllowChainedEnvironmentAccess", BindingFlags.NonPublic | BindingFlags.Instance); 
pi.SetValue(context, true, null); 

完全不支持这么谨慎使用:-)

+0

我有一个客户端没有硬编码的知识要求工作流程。我们习惯于BPM,您可以通过传入名称,值对来初始化字段,询问正在运行的进程以获取字段列表然后设置它们等来创建进程。它更灵活,可发现并且解耦运行时安全的成本。从BPM转向WF就像是从动态类型语言转变为静态类型语言。我认为我们有两个选择:用类型为Dictionary 的变量伪造它,或者询问WSDL。 – TrueWill 2010-12-03 15:52:19