2012-01-11 36 views
2

鉴于工作流基金会4运行时正在对网站工作;)检索工作流的参数(使用默认值)?

我们需要获取工作流的参数,以显示用户输入参数的编辑器。为此,我们需要包含名称,类型和默认值的所有参数,以及是否需要参数。

工作流程存储为XAML文件。

如何做到这一点?数据似乎在活动元数据中,似乎在工作流程外不可用。另外,工作流引擎ModelService适用于Designer,并且有很多开销。

任何简单的方法来检索这些信息?

回答

0

加载它作为DynamicActivity和遍历Properties财产

var dynamicActivity = ActivityXamlServices.Load(foo) as DynamicActivity 
foreach(DynamicActivityProperty prop in dynamicActivity.Properties) 
{ 
    // ... 
} 

UPDATE:错过默认值部分

foreach (var prop in dynamicActivity .Properties) 
{ 
    object defaultValue; 
    if (prop.Value == null) 
    { 
     defaultValue = null; 
    } 
    else 
    { 
     Type genericTypeDefinition = prop.Type.GetGenericTypeDefinition(); 
     if (genericTypeDefinition == typeof(InArgument<>) || genericTypeDefinition == typeof(InOutArgument<>)) 
     { 
      var valueProp = prop.Value.GetType().GetProperty("Expression", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly); 
      var expression = valueProp.GetValue(prop.Value, null); 

      var expressionValueProp = expression.GetType().GetProperty("Value"); 
      defaultValue = expressionValueProp.GetValue(expression, null); 
     } 
    } 
} 

不能完全保证,有一些检查,你必须做的。

+0

从* Activity *转换为* DynamicActivity *无效。 – Joao 2012-01-11 22:57:48

+0

你确定吗? DynamicActivity:活动。 此活动是通过您的工作流设计器上的ActivityBuilder创建的? – 2012-01-11 23:17:54

+0

如果它是通过代码创建的* CustomCodeActivity *会怎么样?该演员阵容并非总是有效。 – Joao 2012-01-11 23:40:05

2

我已经做了类似的事情。如果你想要一个通用的方法,反思可能是你最好的(也是唯一的)选择。

// Just an holder for InArgument informations 
class InArgumentInfo 
{ 
    public string InArgumentName { get; set; } 
    public string InArgumentDescription { get; set; } 
    public bool InArgumentIsRequired { get; set; } 
} 

static ICollection<InArgumentInfo> GetInArgumentsInfos(Activity activity) 
{ 
    var properties = activity.GetType() 
     .GetProperties() 
     .Where(p => typeof(InArgument).IsAssignableFrom(p.PropertyType)) 
     .ToList(); 

    var argumentsCollection = new Collection<InArgumentInfo>(); 

    foreach (var property in properties) 
    { 
     var descAttribute = property 
      .GetCustomAttributes(false) 
      .OfType<DescriptionAttribute>() 
      .FirstOrDefault(); 

     string description = descAttribute != null && !string.IsNullOrEmpty(descAttribute.Description) ? 
      descAttribute.Description : 
      string.Empty; 

     bool isRequired = property 
      .GetCustomAttributes(false) 
      .OfType<RequiredArgumentAttribute>() 
      .Any(); 

     argumentsCollection.Add(new InArgumentInfo 
     { 
      InArgumentName = property.Name, 
      InArgumentDescription = description, 
      InArgumentIsRequired = isRequired 
     }); 
    } 

    return argumentsCollection; 
} 

这样,您不仅可以检索参数的名称,而且还可以检索参数的属性保存的其他信息。例如,我选择通过[说明]属性(例如,而不是MyPropertyName用户看到“我的属性名称”)为用户提供参数。

注意:如果你能保证你的活动是一个ActivityBuilderDynamicActivity他们都有Properties属性,您可以使用,但原理是一样的。

+0

+1。你可以重新使用DynamicActivityProperty(这是众所周知的,并拥有所有这些信息),并制定一个方法,检查是否ActivityBuilder或DynamicActivity并返回属性道具,并在其他情况下使用反射来获取道具。 ;] – 2012-01-11 23:58:40

+0

当然,这是一个选项。我的猜测是*属性*属性也使用幕后反射。 * DynamicActivity *实现[ICustomTypeDescriptor](http://msdn.microsoft.com/en-us/library/system。componentmodel.icustomtypedescriptor.aspx)。 – Joao 2012-01-12 00:03:54