.NET Framework 4.5부터 C# 식은 Windows WF(Workflow Foundation)에서 지원됩니다. .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부터 C# 식은 Windows WF(Workflow Foundation)에서 지원됩니다. .NET Framework 4.5를 대상으로 하는 Visual Studio 2012에서 만든 C# 워크플로 프로젝트는 C# 식을 사용하고 Visual Basic 워크플로 프로젝트는 Visual Basic 식을 사용합니다. 원하는 C# 식을 지정하려면 C# 식 Enter라는 상자에 입력합니다. 이 레이블은 디자이너 또는 워크플로 디자이너의 활동에서 활동을 선택할 때 속성 창에 표시됩니다. 다음 예제에서는 두 개의 WriteLine
활동이 Sequence
에 포함되며, 이는 NoPersistScope
안에 위치합니다.
비고
C# 식은 Visual Studio에서만 지원되며 다시 호스팅된 워크플로 디자이너에서는 지원되지 않습니다. 다시 호스팅된 디자이너에서 지원되는 새로운 WF45 기능에 대한 자세한 내용은 다시 호스트된 워크플로 디자이너의 새 Workflow Foundation 4.5 기능에 대한 지원을 참조하세요.
이전 버전과의 호환성
.NET Framework 4.6.1로 마이그레이션된 기존 .NET Framework 4 C# 워크플로 프로젝트의 Visual Basic 식이 지원됩니다. Visual Basic 식이 유효한 C# 구문이 아니면 워크플로 디자이너에서 Visual Basic 식을 볼 때 기존 Visual Basic 식의 텍스트 가 XAML에서 설정된 값으로 바뀝니다. Visual Basic 식이 유효한 C# 구문이면 식이 표시됩니다. Visual Basic 식을 C#으로 업데이트하려면 워크플로 디자이너에서 편집하고 해당하는 C# 식을 지정할 수 있습니다. Visual Basic 식을 C#으로 업데이트할 필요는 없지만 워크플로 디자이너에서 식이 업데이트되면 C#으로 변환되고 Visual Basic으로 되돌릴 수 없습니다.
코드 워크플로에서 C# 식 사용
C# 식은 .NET Framework 4.6.1 코드 기반 워크플로에서 지원되지만 워크플로를 호출하기 전에 C# 식을 사용하여 TextExpressionCompiler.Compile컴파일해야 합니다. 워크플로 작성자는 CSharpValue
를 식의 r-값을 나타내는 데, 그리고 CSharpReference
를 식의 l-값을 나타내는 데 사용할 수 있습니다. 다음 예제에서는 Assign
활동과 WriteLine
활동이 Sequence
활동에 포함된 워크플로가 생성됩니다. A CSharpReference
는 식의 To
인수에 Assign
대해 지정되고 식의 l 값을 나타냅니다.
CSharpValue
는 Value
의 인수와 Assign
의 인수에 대해 지정되며, 이 두 식의 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# 식이 컴파일되지 않은 경우 워크플로가 호출될 때 다음과 유사한 메시지와 함께 예외가 발생합니다: '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);
}
동적 작업에서 CompileExpressions
C# 식을 컴파일하는 오버로드에는 몇 가지 차이점이 있습니다.
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# 식을 사용합니다.
자유로운 Xaml
C# 식은 유연한 XAML 워크플로에서 지원됩니다. 느슨한 XAML 워크플로를 로드하고 호출하는 워크플로 호스트 프로그램은 .NET Framework 4.6.1을 대상으로 해야 하며CompileExpressions(기본값: true
)로 설정 false
해야 합니다.
CompileExpressions를 true
로 설정하려면 ActivityXamlServicesSettings 속성이 CompileExpressions으로 설정된 true
인스턴스를 생성하여 ActivityXamlServices.Load에 매개 변수로 전달하십시오.
CompileExpressions
가 true
으로 설정되지 않으면, 다음과 유사한 메시지와 함께 NotSupportedException가 발생합니다: Expression Activity type 'CSharpValue
1'는 실행하려면 컴파일이 필요합니다. 워크플로가 컴파일되었는지 확인하세요.'
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 파일을 AWorkflowService
로 로드한 다음 Body
섹션에서 설명한 메서드에 전달 WorkflowService
CompileExpressions
합니다. 다음 예제에서는 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