Batasan Deklaratif

Batasan deklaratif memberikan metode validasi yang kuat untuk suatu aktivitas dan hubungannya dengan aktivitas lain. Batasan dikonfigurasi untuk aktivitas selama proses penulisan, tetapi batasan tambahan juga dapat ditentukan oleh host alur kerja. Topik ini memberikan gambaran umum tentang menggunakan batasan deklaratif untuk memberikan validasi aktivitas.

Menggunakan Batasan Deklaratif

Batasan adalah aktivitas yang berisi logika validasi. Aktivitas batasan ini dapat ditulis dalam kode atau di XAML. Setelah sebuah aktivitas kendala dibuat, penulis aktivitas menambahkan kendala ini ke properti aktivitas Constraints untuk memvalidasi, atau mereka menggunakan kendala tersebut untuk memberikan validasi tambahan melalui properti AdditionalConstraints dari instans ValidationSettings. Logika validasi dapat terdiri dari validasi sederhana seperti memvalidasi metadata aktivitas, tetapi juga dapat melakukan validasi yang memperhitungkan hubungan aktivitas saat ini dengan induk, anak, dan aktivitas saudaranya. Batasan ditulis dengan menggunakan Constraint<T> aktivitas, dan beberapa aktivitas validasi tambahan disediakan untuk membantu pembuatan kesalahan dan peringatan validasi dan untuk memberikan informasi tentang aktivitas terkait dalam alur kerja.

AssertValidation dan AddValidationError

Aktivitas AssertValidation mengevaluasi ekspresi yang direferensikan oleh propertinya Assertion, dan jika ekspresi tersebut dievaluasi menjadi false, kesalahan validasi atau peringatan ditambahkan ke ValidationResults. Properti Message menjelaskan kesalahan validasi dan IsWarning properti menunjukkan apakah kegagalan validasi adalah kesalahan atau peringatan. Nilai defaultnya untuk IsWarning adalah false.

Dalam contoh berikut, batasan dinyatakan yang mengembalikan peringatan validasi jika DisplayName aktivitas yang divalidasi adalah dua karakter atau panjangnya kurang. Parameter jenis generik yang digunakan untuk Constraint<T> menentukan jenis aktivitas yang divalidasi oleh batasan. Batasan ini digunakan Activity sebagai jenis generik dan dapat digunakan untuk memvalidasi semua jenis aktivitas.

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

Untuk menentukan batasan aktivitas ini, batasan ini ditambahkan ke Constraints aktivitas, seperti yang ditunjukkan dalam contoh kode berikut.

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

    // Activity implementation omitted.
}

Host juga dapat menentukan batasan ini untuk aktivitas dalam alur kerja dengan menggunakan AdditionalConstraints, yang tercakup di bagian berikutnya.

Aktivitas AddValidationError ini digunakan untuk menghasilkan kesalahan validasi atau peringatan tanpa memerlukan evaluasi ekspresi. Propertinya mirip dengan AssertValidation dan dapat digunakan dengan aktivitas pengendalian aliran dari batasan seperti aktivitas If.

Aktivitas Hubungan Alur Kerja

Beberapa aktivitas validasi tersedia yang memberikan informasi tentang aktivitas lain dalam alur kerja sehubungan dengan aktivitas yang sedang divalidasi. GetParentChain mengembalikan kumpulan aktivitas yang mengandung semua aktivitas antara aktivitas saat ini dan aktivitas induk. GetChildSubtree menyediakan kumpulan aktivitas yang berisi aktivitas anak dalam pola rekursif, dan GetWorkflowTree mendapatkan semua aktivitas dalam alur kerja.

Dalam contoh berikut, aktivitas CreateState didefinisikan. Aktivitas CreateState harus dimuat dalam CreateCountry aktivitas, dan GetParent metode mengembalikan batasan yang memberlakukan persyaratan ini. GetParent GetParentChain menggunakan aktivitas bersama dengan aktivitas ForEach<T> untuk memeriksa aktivitas induk dari aktivitas CreateState guna menentukan apakah persyaratan terpenuhi.

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

Batasan Tambahan

Penulis host alur kerja dapat menentukan batasan validasi tambahan untuk aktivitas dalam alur kerja dengan membuat batasan dan menambahkannya ke kamus dari sebuah instans AdditionalConstraints. Setiap item di AdditionalConstraints berisi jenis aktivitas yang batasannya berlaku dan daftar batasan tambahan untuk jenis aktivitas tersebut. Saat validasi dipanggil untuk alur kerja, setiap aktivitas dari jenis yang ditentukan, termasuk kelas turunan, mengevaluasi batasan. Dalam contoh ini, ActivityDisplayNameIsNotSetWarning batasan dari bagian sebelumnya diterapkan ke semua aktivitas dalam alur kerja.

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

Jika properti OnlyUseAdditionalConstraints dari ValidationSettings adalah true, maka hanya batasan tambahan yang ditentukan yang dievaluasi ketika validasi dipanggil melalui Validate. Ini dapat berguna untuk memeriksa alur kerja untuk konfigurasi validasi tertentu. Namun perhatikan bahwa ketika alur kerja dipanggil, logika validasi yang dikonfigurasi dalam alur kerja dievaluasi dan harus lulus agar alur kerja berhasil dimulai. Untuk informasi selengkapnya tentang memanggil validasi, lihat Memanggil Validasi Aktivitas.