.NET Framework 4.5 以降、Windows Workflow Foundation (WF) では C# 式がサポートされています。 .NET Framework 4.5 を対象とする Visual Studio 2012 で作成された新しい C# ワークフロー プロジェクトは C# 式を使用し、Visual Basic ワークフロー プロジェクトでは Visual Basic 式を使用します。 Visual Basic 式を使用する既存の .NET Framework 4 ワークフロー プロジェクトは、プロジェクト言語に関係なく .NET Framework 4.6.1 に移行でき、サポートされています。 このトピックでは、WF での C# 式の概要について説明します。
ワークフローでの C# 式の使用
ワークフロー デザイナーでの C# 式の使用
.NET Framework 4.5 以降、Windows Workflow Foundation (WF) では C# 式がサポートされています。 .NET Framework 4.5 を対象とする Visual Studio 2012 で作成された C# ワークフロー プロジェクトでは C# 式が使用され、Visual Basic ワークフロー プロジェクトでは Visual Basic 式が使用されます。 目的の C# 式を指定するには、[ Enter a C# expression]\(C# 式を入力する\) というラベルのボックスに入力します。 このラベルは、デザイナーでアクティビティが選択されている場合、またはワークフロー デザイナーのアクティビティでプロパティ ウィンドウに表示されます。 次の例では、2 つのWriteLine
アクティビティが、NoPersistScope
内のSequence
内に含まれています。
注
C# 式は Visual Studio でのみサポートされ、再ホストされたワークフロー デザイナーではサポートされません。 再ホストされたデザイナーでサポートされる新しい WF45 機能の詳細については、「 再ホストされたワークフロー デザイナーでの新しい Workflow Foundation 4.5 機能のサポート」を参照してください。
下位互換性
.NET Framework 4.6.1 に移行された既存の .NET Framework 4 C# ワークフロー プロジェクトの Visual Basic 式がサポートされています。 Visual Basic 式がワークフロー デザイナーで表示されると、Visual Basic 式が有効な C# 構文でない限り、既存の Visual Basic 式のテキストが XAML で設定された値に置き換えられます。 Visual Basic 式が有効な C# 構文である場合は、式が表示されます。 Visual Basic 式を C# に更新するには、ワークフロー デザイナーでそれらを編集し、同等の C# 式を指定します。 Visual Basic 式を C# に更新する必要はありませんが、ワークフロー デザイナーで式が更新されると、C# に変換され、Visual Basic に戻さない場合があります。
コード ワークフローでの C# 式の使用
C# 式は .NET Framework 4.6.1 コード ベースのワークフローでサポートされていますが、ワークフローを呼び出す前に、 TextExpressionCompiler.Compileを使用して C# 式をコンパイルする必要があります。 ワークフロー作成者は、 CSharpValue
を使用して式の r 値を表し、 CSharpReference
を使用して式の l 値を表すことができます。 次の例では、Assign
アクティビティと、Sequence
アクティビティに含まれるWriteLine
アクティビティを使用してワークフローを作成します。
CSharpReference
は、Assign
のTo
引数に指定され、式の l 値を表します。
CSharpValue
は、Assign
のValue
引数と、WriteLine
のText
引数に指定され、これら 2 つの式の r 値を表します。
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);
ワークフローが構築されると、 CompileExpressions
ヘルパー メソッドを呼び出して C# 式がコンパイルされ、ワークフローが呼び出されます。 次の例は、 CompileExpressions
メソッドです。
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);
}
注
C# 式がコンパイルされていない場合は、次のようなメッセージでワークフローが呼び出されたときに NotSupportedException がスローされます。 Expression Activity type 'CSharpValue
1' を実行するにはコンパイルが必要です。 ワークフローがコンパイルされていることを確認してください。
カスタム コード ベースのワークフローで DynamicActivity
を使用する場合は、次のコード例に示すように、 CompileExpressions
メソッドにいくつかの変更が必要です。
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);
}
動的アクティビティで C# 式をコンパイルする CompileExpressions
オーバーロードには、いくつかの違いがあります。
CompileExpressions
するパラメーターはDynamicActivity
です。型名と名前空間は、
DynamicActivity.Name
プロパティを使用して取得されます。TextExpressionCompilerSettings.ForImplementation
はtrue
に設定されます。CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation
は、CompiledExpressionInvoker.SetCompiledExpressionRoot
の代わりに呼び出されます。
コードで式を操作する方法の詳細については、「 命令型コードを使用したワークフロー、アクティビティ、および式の作成」を参照してください。
XAML ワークフローでの C# 式の使用
C# 式は XAML ワークフローでサポートされています。 コンパイル済みの XAML ワークフローは型にコンパイルされ、ルーズ XAML ワークフローはランタイムによって読み込まれ、ワークフローの実行時にアクティビティ ツリーにコンパイルされます。
コンパイル済み Xaml
C# 式は、.NET Framework 4.6.1 を対象とする C# ワークフロー プロジェクトの一部として型にコンパイルされるコンパイル済み XAML ワークフローでサポートされます。 コンパイル済み XAML は Visual Studio でのワークフロー作成の既定の種類であり、.NET Framework 4.6.1 を対象とする Visual Studio で作成された C# ワークフロー プロジェクトでは C# 式が使用されます。
Loose Xaml
C# 式は、緩やかな XAML ワークフローでサポートされています。 緩やかな XAML ワークフローを読み込んで呼び出すワークフロー ホスト プログラムは、.NET Framework 4.6.1 を対象とし、 CompileExpressions を true
に設定する必要があります (既定値は false
)。
CompileExpressionsをtrue
に設定するには、CompileExpressions プロパティを true
に設定してActivityXamlServicesSettings インスタンスを作成し、ActivityXamlServices.Loadするパラメーターとして渡します。
CompileExpressions
Is not set to true
, a NotSupportedException will be thrown with a message with the following: Expression Activity type 'CSharpValue
1' requires compilation to run. ワークフローがコンパイルされていることを確認してください。
ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;
XAML ワークフローの操作の詳細については、「XAML との間での ワークフローとアクティビティのシリアル化」を参照してください。
XAMLX ワークフロー サービスでの C# 式の使用
C# 式は、XAMLX ワークフロー サービスでサポートされています。 ワークフロー サービスが IIS または WAS でホストされている場合、追加の手順は必要ありませんが、XAML ワークフロー サービスがセルフホステッドの場合は、C# 式をコンパイルする必要があります。 セルフホステッド XAMLX ワークフロー サービスで C# 式をコンパイルするには、まず XAMLX ファイルをWorkflowService
に読み込み、次にコード ワークフローの前の「C# 式を使用する」セクションで説明したCompileExpressions
メソッドにWorkflowService
のBody
を渡します。 次の例では、XAMLX ワークフロー サービスが読み込まれ、C# 式がコンパイルされ、ワークフロー サービスが開き、要求が待機されます。
// 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();
C# 式がコンパイルされていない場合、 Open
操作は成功しますが、呼び出されるとワークフローは失敗します。 次の CompileExpressions
メソッドは、 前のコード ワークフローでの C# 式の使用に関するセクションの メソッドと同じです。
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);
}
.NET