Поделиться через


Декларативные ограничения

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

Использование декларативных ограничений

Ограничение — это действие, содержащее логику проверки. Это действие ограничения можно создать в коде или в XAML. После создания действия ограничения авторы действий добавляют это ограничение в свойство Constraints для проверки или используют это ограничение для дополнительной проверки, применяя свойство AdditionalConstraints экземпляра ValidationSettings. Логика проверки может состоять из простых проверок, таких как проверка метаданных действия, но она также может выполнять проверку, которая учитывает связь текущего действия с родительскими, дочерними и одноуровневым действиями. Ограничения создаются с помощью Constraint<T> активности, а несколько дополнительных проверочных активностей предоставляются для создания ошибок проверки и предупреждений, а также для предоставления информации о связанных активностях в рабочем процессе.

AssertValidation и AddValidationError

Действие AssertValidation вычисляет выражение, на которое ссылается его Assertion свойство, и если выражение оценивается как false, в ValidationResults добавляется ошибка проверки или предупреждение. Свойство Message описывает ошибку проверки и IsWarning свойство указывает, является ли ошибка проверки ошибкой или предупреждением. Значение по умолчанию для IsWarningfalse.

В следующем примере объявляется ограничение, которое возвращает предупреждение о проверке, если длина проверяемого действия составляет два символа или меньше. Параметр универсального типа для Constraint<T>, который определяет тип действия, проверяемого ограничением. Это ограничение используется Activity в качестве универсального типа и может использоваться для проверки всех типов действий.

public static Constraint ActivityDisplayNameIsNotSetWarning()  
{  
    DelegateInArgument<Activity> element = new DelegateInArgument<Activity>();  
  
    return new Constraint<Activity>  
    {  
        Body = new ActivityAction<Activity, ValidationContext>  
        {  
            Argument1 = element,  
            Handler = new AssertValidation  
            {  
                IsWarning = true,  
                Assertion = new InArgument<bool>(env => (element.Get(env).DisplayName.Length > 2)),  
                Message = new InArgument<string>("It is a best practice to have a DisplayName of more than 2 characters."),  
            }  
        }  
    };  
}  

Чтобы задать это ограничение для действия, его добавляют в Constraints действия, как показано в следующем примере кода.

public sealed class SampleActivity : CodeActivity  
{  
    public SampleActivity()  
    {  
        base.Constraints.Add(ActivityDisplayNameIsNotSetWarning());  
    }  
  
    // Activity implementation omitted.  
}  

Ведущий также может указать это ограничение для действий в рабочем процессе с помощью AdditionalConstraints, о чем говорится в следующем разделе.

Действие AddValidationError используется для создания ошибки проверки или предупреждения, не требуя оценки выражения. Его свойства похожи на AssertValidation и могут использоваться в сочетании с действиями управления потоком ограничения, такими как деятельность If.

Действия связи рабочего процесса

Некоторые действия проверки доступны, которые предоставляют информацию о других действиях в рабочем процессе в связи с проверяемым действием. GetParentChain возвращает коллекцию действий, содержащих все действия между текущим действием и корневым действием. GetChildSubtree предоставляет коллекцию задач, содержащих дочерние задачи в рекурсивной структуре, и GetWorkflowTree получает все задачи в рабочем процессе.

В следующем примере определяется активность CreateState. Действие CreateState должно содержаться в CreateCountry действии, а GetParent метод возвращает ограничение, которое применяет это требование. GetParent GetParentChain использует действие в сочетании с действием ForEach<T> для проверки родительских действий CreateState, чтобы определить, выполнено ли требование.

public sealed class CreateState : CodeActivity  
{  
    public CreateState()  
    {  
        base.Constraints.Add(CheckParent());  
        this.Cities = new List<Activity>();
    }  
  
    public List<Activity> Cities { get; set; }  
  
    public string Name { get; set; }
  
    static Constraint CheckParent()  
    {  
        DelegateInArgument<CreateState> element = new DelegateInArgument<CreateState>();  
        DelegateInArgument<ValidationContext> context = new DelegateInArgument<ValidationContext>();
        Variable<bool> result = new Variable<bool>();  
        DelegateInArgument<Activity> parent = new DelegateInArgument<Activity>();  
  
        return new Constraint<CreateState>  
        {
            Body = new ActivityAction<CreateState,ValidationContext>  
            {
                Argument1 = element,  
                Argument2 = context,  
                Handler = new Sequence  
                {  
                    Variables =  
                    {  
                        result
                    },  
                    Activities =  
                    {  
                        new ForEach<Activity>  
                        {
                            Values = new GetParentChain  
                            {  
                                ValidationContext = context
                            },  
                            Body = new ActivityAction<Activity>  
                            {
                                Argument = parent,
                                Handler = new If()  
                                {
                                    Condition = new InArgument<bool>((env) => object.Equals(parent.Get(env).GetType(),typeof(CreateCountry))),
                                    Then = new Assign<bool>  
                                    {  
                                        Value = true,  
                                        To = result  
                                    }  
                                }  
                            }
                        },  
                        new AssertValidation  
                        {  
                            Assertion = new InArgument<bool>(result),  
                            Message = new InArgument<string> ("CreateState has to be inside a CreateCountry activity"),
                        }  
                    }  
                }  
            }  
        };  
    }  
  
    protected override void Execute(CodeActivityContext context)  
    {  
        // not needed for the sample  
    }  
}  

Дополнительные ограничения

Авторы узла рабочего процесса могут указывать дополнительные ограничения проверки для действий в рабочем процессе, создавая ограничения и добавляя их в AdditionalConstraints словарь экземпляра ValidationSettings . Каждый элемент содержит AdditionalConstraints тип действия, для которого применяются ограничения, и список дополнительных ограничений для этого типа действия. При вызове проверки для рабочего процесса каждое действие указанного типа, включая производные классы, оценивает ограничения. В этом примере ActivityDisplayNameIsNotSetWarning ограничение из предыдущего раздела применяется ко всем действиям в рабочем процессе.

Activity wf = new Sequence  
{  
    // Workflow Details Omitted.  
};  
  
ValidationSettings settings = new ValidationSettings()  
{  
  
    AdditionalConstraints =  
    {  
        {typeof(Activity), new List<Constraint> {ActivityDisplayNameIsNotSetWarning()}},
    }  
};  
  
// Validate the workflow.  
ValidationResults results = ActivityValidationServices.Validate(wf, settings);  
  
// Evaluate the results.  
if (results.Errors.Count == 0 && results.Warnings.Count == 0)  
{  
    Console.WriteLine("No warnings or errors");  
}  
else  
{  
    foreach (ValidationError error in results.Errors)  
    {  
        Console.WriteLine("Error in " + error.Source.DisplayName + ": " + error.Message);  
    }  
    foreach (ValidationError warning in results.Warnings)  
    {  
        Console.WriteLine("Warning in " + warning.Source.DisplayName + ": " + warning.Message);  
    }  
}  

Если свойство OnlyUseAdditionalConstraints имеет значение ValidationSettings, то при вызове true вычисляются только указанные дополнительные ограничения. Это может быть полезно для проверки рабочих процессов для определенных конфигураций проверки. Обратите внимание, что при вызове рабочего процесса должна пройти проверка на соответствие логики, настроенной в рабочем процессе, чтобы рабочий процесс успешно начался. Дополнительные сведения о вызове проверки см. в разделе "Вызов проверки действия".