Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dimulai dengan .NET Framework 4.5, ekspresi C# didukung di Windows Workflow Foundation (WF). Proyek alur kerja C# baru yang dibuat di Visual Studio 2012 yang menargetkan .NET Framework 4.5 menggunakan ekspresi C#, dan proyek alur kerja Visual Basic menggunakan ekspresi Visual Basic. Proyek alur kerja .NET Framework 4 yang ada yang menggunakan ekspresi Visual Basic dapat dimigrasikan ke .NET Framework 4.6.1 terlepas dari bahasa proyek dan didukung. Topik ini memberikan gambaran umum tentang ekspresi C# di WF.
Menggunakan ekspresi C# dalam alur kerja
Menggunakan ekspresi C# di Perancang Alur Kerja
Dimulai dengan .NET Framework 4.5, ekspresi C# didukung di Windows Workflow Foundation (WF). Proyek alur kerja C# yang dibuat di Visual Studio 2012 yang menargetkan .NET Framework 4.5 menggunakan ekspresi C#, sementara proyek alur kerja Visual Basic menggunakan ekspresi Visual Basic. Untuk menentukan ekspresi C# yang diinginkan, ketikkan ke dalam kotak berlabel Masukkan ekspresi C#. Label ini ditampilkan di jendela properti saat aktivitas dipilih di perancang, atau pada aktivitas di perancang alur kerja. Dalam contoh berikut, dua WriteLine aktivitas terkandung dalam Sequence di dalam NoPersistScope.
Nota
Ekspresi C# hanya didukung di Visual Studio, dan tidak didukung di perancang alur kerja yang dihost ulang. Untuk informasi selengkapnya tentang fitur WF45 baru yang didukung di perancang yang dihost ulang, lihat Dukungan untuk Fitur New Workflow Foundation 4.5 di Perancang Alur Kerja yang Dihosting Ulang.
Kompatibilitas mundur
Ekspresi Visual Basic dalam proyek alur kerja .NET Framework 4 C# yang sudah ada yang telah dimigrasikan ke .NET Framework 4.6.1 didukung. Saat ekspresi Visual Basic ditampilkan dalam perancang alur kerja, teks ekspresi Visual Basic yang ada diganti dengan Nilai diatur dalam XAML, kecuali ekspresi Visual Basic adalah sintaks C# yang valid. Jika ekspresi Visual Basic adalah sintaks C# yang valid, maka ekspresi ditampilkan. Untuk memperbarui ekspresi Visual Basic ke C#, Anda dapat mengeditnya di perancang alur kerja dan menentukan ekspresi C# yang setara. Tidak diperlukan untuk memperbarui ekspresi Visual Basic ke C#, tetapi setelah ekspresi diperbarui dalam perancang alur kerja, ekspresi tersebut dikonversi ke C# dan mungkin tidak dikembalikan ke Visual Basic.
Menggunakan ekspresi C# dalam alur kerja kode
Ekspresi C# didukung dalam alur kerja berbasis kode .NET Framework 4.6.1, tetapi sebelum alur kerja dapat dipanggil ekspresi C# harus dikompilasi menggunakan TextExpressionCompiler.Compile. Penulis alur kerja dapat menggunakan CSharpValue untuk mewakili nilai r ekspresi, dan CSharpReference untuk mewakili nilai l ekspresi. Dalam contoh berikut, alur kerja dibuat dengan Assign tindak aktivitas dan WriteLine tindak aktivitas yang terkandung dalam Sequence tindak aktivitas.
CSharpReference telah ditetapkan untuk argumen To dari Assign, dan mewakili nilai l dari ekspresi.
CSharpValue ditentukan untuk Value argumen Assign, dan untuk Text argumen WriteLine, dan mewakili nilai r untuk kedua ekspresi tersebut.
Variable<int> n = new Variable<int>
{
Name = "n"
};
Activity wf = new Sequence
{
Variables = { n },
Activities =
{
new Assign<int>
{
To = new CSharpReference<int>("n"),
Value = new CSharpValue<int>("new Random().Next(1, 101)")
},
new WriteLine
{
Text = new CSharpValue<string>("\"The number is \" + n")
}
}
};
CompileExpressions(wf);
WorkflowInvoker.Invoke(wf);
Setelah alur kerja dibangun, ekspresi C# dikompilasi dengan memanggil metode pembantu CompileExpressions lalu alur kerja dipanggil. Contoh berikut adalah CompileExpressions metode .
static void CompileExpressions(Activity activity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions.
string activityName = activity.GetType().ToString();
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = activity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = false
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { activity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRoot(
activity, compiledExpressionRoot);
}
Nota
Jika ekspresi C# tidak dikompilasi, NotSupportedException akan ditampilkan saat alur kerja dipanggil dengan pesan yang mirip dengan yang berikut ini: Expression Activity type 'CSharpValue1' memerlukan kompilasi untuk dijalankan. Pastikan bahwa alur kerja telah dikompilasi.'
Jika alur kerja berbasis kode kustom Anda menggunakan DynamicActivity, maka beberapa perubahan pada CompileExpressions metode diperlukan, seperti yang ditunjukkan dalam contoh kode berikut.
static void CompileExpressions(DynamicActivity dynamicActivity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions. For Dynamic Activities this can be retrieved using the
// name property , which must be in the form Namespace.Type.
string activityName = dynamicActivity.Name;
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = dynamicActivity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = true
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { dynamicActivity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(
dynamicActivity, compiledExpressionRoot);
}
Ada beberapa perbedaan dalam CompileExpressions overload yang mengkompilasi ekspresi C# pada aktivitas dinamis.
Parameter ke
CompileExpressionsadalahDynamicActivity.Nama jenis dan namespace diambil melalui properti
DynamicActivity.Name.TextExpressionCompilerSettings.ForImplementationdiatur ketrue.CompiledExpressionInvoker.SetCompiledExpressionRootForImplementationdipanggil alih-alihCompiledExpressionInvoker.SetCompiledExpressionRoot.
Untuk informasi selengkapnya tentang bekerja dengan ekspresi dalam kode, lihat Penulisan Alur Kerja, Aktivitas, dan Ekspresi Menggunakan Kode Imperatif.
Menggunakan ekspresi C# dalam alur kerja XAML
Ekspresi C# didukung dalam alur kerja XAML. Alur kerja XAML yang telah dikompilasi menjadi tipe, dan alur kerja XAML yang belum dikompilasi dimuat oleh waktu jalan dan dikompilasi ke dalam hierarki aktivitas saat alur kerja dijalankan.
Xaml yang Dikompilasi
Ekspresi C# didukung dalam alur kerja XAML yang telah dikompilasi menjadi tipe sebagai bagian dari proyek alur kerja C# yang menargetkan .NET Framework 4.6.1. XAML yang dikompilasi adalah jenis penulisan alur kerja default di Visual Studio, dan proyek alur kerja C# yang dibuat di Visual Studio yang menargetkan .NET Framework 4.6.1 menggunakan ekspresi C#.
Xaml Fleksibel
Ekspresi C# didukung dalam alur kerja XAML yang longgar. Program host alur kerja yang memuat dan memanggil alur kerja XAML yang longgar harus menargetkan .NET Framework 4.6.1, dan CompileExpressions harus diatur ke true (defaultnya adalah false). Untuk mengatur CompileExpressions ke true, buat instance ActivityXamlServicesSettings dengan properti CompileExpressions diatur ke true, lalu berikan sebagai parameter ke ActivityXamlServices.Load. Jika CompileExpressions tidak diatur ke true, akan melemparkan NotSupportedException dengan pesan yang mirip dengan yang berikut ini: Expression Activity type 'CSharpValue1' memerlukan kompilasi untuk dijalankan. Pastikan bahwa alur kerja telah dikompilasi.'
ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;
Untuk informasi selengkapnya tentang bekerja dengan alur kerja XAML, lihat Serialisasi Alur Kerja dan Aktivitas ke dan dari XAML.
Menggunakan ekspresi C# di layanan alur kerja XAMLX
Ekspresi C# didukung dalam layanan alur kerja XAMLX. Ketika layanan alur kerja dihosting di IIS atau WAS maka tidak ada langkah tambahan yang diperlukan, tetapi jika layanan alur kerja XAML dihost sendiri, ekspresi C# harus dikompilasi. Untuk menyusun ekspresi C# dalam layanan alur kerja XAMLX yang dihost sendiri, muat terlebih dahulu file XAMLX ke dalam WorkflowService, lalu teruskan Body dari WorkflowService ke metode CompileExpressions yang dijelaskan di bagian sebelumnya Menggunakan ekspresi C# dalam alur kerja kode. Dalam contoh berikut, layanan alur kerja XAMLX dimuat, ekspresi C# dikompilasi, lalu layanan alur kerja dibuka dan menunggu permintaan.
// Load the XAMLX workflow service.
WorkflowService workflow1 =
(WorkflowService)XamlServices.Load(xamlxPath);
// Compile the C# expressions in the workflow by passing the Body to CompileExpressions.
CompileExpressions(workflow1.Body);
// Initialize the WorkflowServiceHost.
var host = new WorkflowServiceHost(workflow1, new Uri("http://localhost:8293/Service1.xamlx"));
// Enable Metadata publishing/
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the WorkflowServiceHost and wait for requests.
host.Open();
Console.WriteLine("Press enter to quit");
Console.ReadLine();
Jika ekspresi C# tidak dikompilasi, Open operasi berhasil tetapi alur kerja akan gagal saat dipanggil. Metode berikut CompileExpressions sama dengan metode dari bagian Menggunakan ekspresi C# sebelumnya di alur kerja kode .
static void CompileExpressions(Activity activity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions.
string activityName = activity.GetType().ToString();
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = activity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = false
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { activity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRoot(
activity, compiledExpressionRoot);
}