Получить аргументы рабочего процесса (со значениями по умолчанию)? - PullRequest
2 голосов
/ 11 января 2012

Данная среда выполнения Workflow Foundation 4 работает с веб-сайтом;)

Нам нужно получить аргументы рабочих процессов, чтобы показать пользователю редактор для ввода аргументов.Для этого нам понадобятся все аргументы с именами, типами и - значениями по умолчанию, а также указание, требуется ли аргумент.

Рабочие процессы хранятся в виде файлов XAML.

Как это сделать?Похоже, что данные находятся в метаданных активности, которые, по-видимому, недоступны вне рабочего процесса.Кроме того, WorkService ModelService предназначен для дизайнера и имеет много накладных расходов.

Есть ли простой способ получить эту информацию?

Ответы [ 2 ]

2 голосов
/ 12 января 2012

Я уже сделал нечто подобное.Отражение может быть вашим лучшим (и единственным) вариантом, если вам нужен общий подход.

// 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;
}

Таким образом, вы можете не только получить имя аргумента, но и другую информацию, хранящуюся в атрибутах аргумента.Например, я хочу дать аргументу удобное для пользователя имя с помощью атрибута [Description] (например, вместо MyPropertyName пользователь видит «Имя моего свойства»).

Примечание : если вы можете убедиться, что ваша деятельность является ActivityBuilder или DynamicActivity , они оба имеют Свойства , которые вы можете использовать, но принцип тот же.

0 голосов
/ 12 января 2012

Загрузить его как DynamicActivity и выполнить итерацию по Properties свойство

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

ОБНОВЛЕНИЕ : пропущенная часть значения по умолчанию

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);
        }
    }
}

Не полностью гарантировано, естьнекоторые проверки, которые вы должны сделать.

...