Restrições declarativas
As restrições declarativas fornecem um método poderoso de validação para uma atividade e suas relações com outras atividades. As restrições são configuradas para uma atividade durante o processo de criação, mas restrições adicionais também podem ser especificadas pelo host do fluxo de trabalho. Este tópico fornece uma visão geral do uso de restrições declarativas para fornecer validação de atividade.
Usando restrições declarativas
Uma restrição é uma atividade que contém lógica de validação. Essa atividade de restrição pode ser criada em código ou em XAML. Depois que uma atividade de restrição é criada, os Constraints autores de atividade adicionam essa restrição à propriedade da atividade a ser validada ou usam a restrição para fornecer validação adicional usando a AdditionalConstraints propriedade de uma ValidationSettings instância. A lógica de validação pode consistir em validações simples, como validar os metadados de uma atividade, mas também pode realizar validações que levam em conta a relação da atividade atual com suas atividades parentais, filhos e irmãos. As restrições são criadas usando a Constraint<T> atividade, e várias atividades de validação adicionais são fornecidas para ajudar na criação de erros e avisos de validação e para fornecer informações sobre atividades relacionadas no fluxo de trabalho.
AssertValidation e AddValidationError
A AssertValidation atividade avalia a expressão referenciada por sua Assertion propriedade e, se a expressão for avaliada como false
, um erro de validação ou aviso será adicionado ao ValidationResults. A Message propriedade descreve o erro de validação e indica IsWarning se a falha de validação é um erro ou um aviso. O valor padrão para IsWarning é false
.
No exemplo a seguir, é declarada uma restrição que retorna um aviso de validação se a atividade que está sendo validada DisplayName tiver dois caracteres ou menos de comprimento. O parâmetro de tipo genérico usado para Constraint<T> especifica o tipo de atividade que é validada pela restrição. Esta restrição usa Activity como o tipo genérico e pode ser usado para validar todos os tipos de atividades.
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."),
}
}
};
}
Para especificar essa restrição para uma atividade, ela é adicionada ao Constraints da atividade, conforme mostrado no código de exemplo a seguir.
public sealed class SampleActivity : CodeActivity
{
public SampleActivity()
{
base.Constraints.Add(ActivityDisplayNameIsNotSetWarning());
}
// Activity implementation omitted.
}
O host também pode especificar essa restrição para atividades em um fluxo de trabalho usando AdditionalConstraints, que é abordado na próxima seção.
A AddValidationError atividade é usada para gerar um erro de validação ou aviso sem exigir a avaliação de uma expressão. Suas propriedades são semelhantes e AssertValidation pode ser usado em conjunto com atividades de controle de fluxo de uma restrição, como a If atividade.
Atividades de relacionamento de fluxo de trabalho
Várias atividades de validação estão disponíveis que fornecem informações sobre as outras atividades no fluxo de trabalho em relação à atividade que está sendo validada. GetParentChain Retorna uma coleção de atividades que contém todas as atividades entre a atividade atual e a atividade raiz. GetChildSubtree Fornece uma coleção de atividades que contém as atividades filho em um padrão recursivo e GetWorkflowTree obtém todas as atividades no fluxo de trabalho.
No exemplo a seguir, uma CreateState
atividade é definida. A CreateState
atividade deve estar contida em uma CreateCountry
atividade e o GetParent
método retorna uma restrição que impõe esse requisito. GetParent
usa a GetParentChain atividade em conjunto com uma ForEach<T> atividade para inspecionar as atividades pai da CreateState
atividade para determinar se o requisito é atendido.
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
}
}
Restrições adicionais
Os autores do host do fluxo de trabalho podem especificar restrições de validação adicionais para atividades em um fluxo de trabalho criando restrições e adicionando-as ao AdditionalConstraints dicionário de uma ValidationSettings instância. Cada item contém AdditionalConstraints o tipo de atividade para o qual as restrições se aplicam e uma lista das restrições adicionais para esse tipo de atividade. Quando a validação é invocada para o fluxo de trabalho, cada atividade do tipo especificado, incluindo classes derivadas, avalia as restrições. Neste exemplo, a ActivityDisplayNameIsNotSetWarning
restrição da seção anterior é aplicada a todas as atividades em um fluxo de trabalho.
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);
}
}
Se a OnlyUseAdditionalConstraints propriedade de is true
, somente as restrições adicionais especificadas serão avaliadas quando a validação for invocada ValidationSettings chamando Validate. Isso pode ser útil para inspecionar fluxos de trabalho para configurações de validação específicas. No entanto, observe que, quando o fluxo de trabalho é invocado, a lógica de validação configurada no fluxo de trabalho é avaliada e deve passar para que o fluxo de trabalho seja iniciado com êxito. Para obter mais informações sobre como invocar a validação, consulte Invocando a validação da atividade.