鉴于工作流基金会4运行时正在对网站工作;)检索工作流的参数(使用默认值)?
我们需要获取工作流的参数,以显示用户输入参数的编辑器。为此,我们需要包含名称,类型和默认值的所有参数,以及是否需要参数。
工作流程存储为XAML文件。
如何做到这一点?数据似乎在活动元数据中,似乎在工作流程外不可用。另外,工作流引擎ModelService适用于Designer,并且有很多开销。
任何简单的方法来检索这些信息?
鉴于工作流基金会4运行时正在对网站工作;)检索工作流的参数(使用默认值)?
我们需要获取工作流的参数,以显示用户输入参数的编辑器。为此,我们需要包含名称,类型和默认值的所有参数,以及是否需要参数。
工作流程存储为XAML文件。
如何做到这一点?数据似乎在活动元数据中,似乎在工作流程外不可用。另外,工作流引擎ModelService适用于Designer,并且有很多开销。
任何简单的方法来检索这些信息?
加载它作为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);
}
}
}
不能完全保证,有一些检查,你必须做的。
我已经做了类似的事情。如果你想要一个通用的方法,反思可能是你最好的(也是唯一的)选择。
// 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用户看到“我的属性名称”)为用户提供参数。
注意:如果你能保证你的活动是一个ActivityBuilder或DynamicActivity他们都有Properties属性,您可以使用,但原理是一样的。
+1。你可以重新使用DynamicActivityProperty(这是众所周知的,并拥有所有这些信息),并制定一个方法,检查是否ActivityBuilder或DynamicActivity并返回属性道具,并在其他情况下使用反射来获取道具。 ;] – 2012-01-11 23:58:40
当然,这是一个选项。我的猜测是*属性*属性也使用幕后反射。 * DynamicActivity *实现[ICustomTypeDescriptor](http://msdn.microsoft.com/en-us/library/system。componentmodel.icustomtypedescriptor.aspx)。 – Joao 2012-01-12 00:03:54
从* Activity *转换为* DynamicActivity *无效。 – Joao 2012-01-11 22:57:48
你确定吗? DynamicActivity:活动。 此活动是通过您的工作流设计器上的ActivityBuilder创建的? – 2012-01-11 23:17:54
如果它是通过代码创建的* CustomCodeActivity *会怎么样?该演员阵容并非总是有效。 – Joao 2012-01-11 23:40:05