Ograniczenia deklaratywne

Ograniczenia deklaratywne zapewniają zaawansowaną metodę weryfikacji działania i jej relacji z innymi działaniami. Ograniczenia są konfigurowane dla działania podczas procesu tworzenia, ale można również określić dodatkowe ograniczenia przez hosta przepływu pracy. Ten temat zawiera omówienie używania ograniczeń deklaratywnych w celu zapewnienia weryfikacji działania.

Używanie ograniczeń deklaratywnych

Ograniczenie to działanie, które zawiera logikę walidacji. To ograniczenie aktywności może być tworzone w kodzie lub w języku XAML. Po utworzeniu aktywności ograniczenia, autorzy aktywności dodają to ograniczenie do właściwości Constraints danej aktywności w celu weryfikacji lub używają ograniczenia w celu zapewnienia dodatkowej weryfikacji, korzystając z właściwości AdditionalConstraints instancji ValidationSettings. Logika walidacji może składać się z prostych walidacji, takich jak weryfikowanie metadanych działania, ale może również wykonywać walidację, która uwzględnia relację bieżącego działania z działaniami nadrzędnymi, podrzędnymi i równorzędnymi. Ograniczenia są tworzone przy użyciu Constraint<T> aktywności, a kilka dodatkowych aktywności walidacyjnych zostało udostępnionych w celu ułatwienia tworzenia błędów i ostrzeżeń walidacji oraz dostarczania informacji o powiązanych aktywnościach w przepływie pracy.

AssertValidation i AddValidationError

Działanie AssertValidation ocenia wyrażenie wskazane przez jego właściwość Assertion, a jeśli wyrażenie przyjmuje wartość false, do elementu ValidationResults zostanie dodany błąd walidacji lub ostrzeżenie. Właściwość Message opisuje błąd weryfikacji, a IsWarning właściwość wskazuje, czy niepowodzenie weryfikacji jest błędem, czy ostrzeżeniem. Wartość domyślna parametru IsWarning to false.

W poniższym przykładzie zdefiniowane jest ograniczenie, które zwraca ostrzeżenie o walidacji, jeśli DisplayName działania, które jest poddawane walidacji, ma długość dwóch znaków lub mniej. Ogólny parametr typu używany dla Constraint<T> określa typ działania, który jest weryfikowany przez ograniczenie. To ograniczenie używa Activity jako typu ogólnego i może służyć do sprawdzania poprawności wszystkich typów działań.

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."),
            }
        }
    };
}

Aby określić to ograniczenie dla działania, jest on dodawany do Constraints działania, jak pokazano w poniższym przykładowym kodzie.

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

    // Activity implementation omitted.
}

Host może również określić to ograniczenie dla działań w przepływie pracy przy użyciu elementu AdditionalConstraints, który został omówiony w następnej sekcji.

Działanie AddValidationError jest używane do generowania błędu weryfikacji lub ostrzeżenia bez konieczności obliczania wyrażenia. Jego właściwości są podobne do AssertValidation i mogą być używane razem z działaniami kontrolującymi przepływem ograniczenia, takimi jak aktywność If.

Działania relacji przepływu pracy

Dostępnych jest kilka działań sprawdzania poprawności, które zawierają informacje o innych działaniach w przepływie pracy w odniesieniu do weryfikowanego działania. GetParentChain Zwraca kolekcję działań, która zawiera wszystkie działania między bieżącym działaniem a działaniem głównym. GetChildSubtree udostępnia kolekcję działań, która zawiera działania podrzędne w sposób rekursywny, a GetWorkflowTree pobiera wszystkie działania w procesie pracy.

W poniższym przykładzie zdefiniowano CreateState aktywność. Działanie CreateState musi być zawarte w CreateCountry działaniu, a GetParent metoda zwraca ograniczenie, które wymusza to wymaganie. GetParent używa działania GetParentChain w połączeniu z działaniem ForEach<T> do sprawdzania działań nadrzędnych działania CreateState w celu określenia, czy wymaganie zostało spełnione.

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

Dodatkowe ograniczenia

Twórcy hostów przepływu pracy mogą określić dodatkowe ograniczenia walidacji dla działań w przepływie pracy, tworząc ograniczenia i dodając je do słownika wystąpienia AdditionalConstraints. Każdy element w programie AdditionalConstraints zawiera typ działania, dla którego mają zastosowanie ograniczenia, oraz listę dodatkowych ograniczeń dla tego typu działania. Po wywołaniu walidacji dla przepływu pracy każde działanie określonego typu, w tym klasy pochodne, ocenia ograniczenia. W tym przykładzie ActivityDisplayNameIsNotSetWarning ograniczenie z poprzedniej sekcji jest stosowane do wszystkich działań w przepływie pracy.

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

Jeśli właściwość OnlyUseAdditionalConstraints obiektu ValidationSettings ma wartość true, to tylko określone dodatkowe ograniczenia są oceniane podczas wywoływania walidacji przez metodę Validate. Może to być przydatne w przypadku inspekcji przepływów pracy pod kątem określonych konfiguracji weryfikacji. Należy jednak pamiętać, że po wywołaniu przepływu pracy logika walidacji skonfigurowana w przepływie pracy jest oceniana i musi zostać przekazana, aby przepływ pracy został pomyślnie uruchomiony. Aby uzyskać więcej informacji na temat wywoływania walidacji, zobacz Wywoływanie walidacji działania.