작업 1: 워크플로 서비스 만들기
이 작업에서는 WCF(Windows Communication Foundation) 계약을 구현하고 서비스의 상태 정보를 SQL 데이터베이스에 저장하는 기본적인 상태 시스템 워크플로 서비스를 만듭니다. 계약 중심 제작 스타일을 통해 이 작업을 수행합니다.
참고
이 워크플로 서비스는 이 자습서의 나머지 연습에서 사용됩니다.
참고
Visual Studio Workflow Designer를 사용하여 워크플로 서비스를 만들거나 관리할 경우 의사 유효성 검사 오류가 발생할 수 있습니다. 프로젝트를 성공적으로 빌드할 수 있으면 유효성 검사 오류를 무시해도 됩니다.
워크플로 서비스를 설정하고 계약을 정의하려면
Visual Studio 2008을 열고 파일을 클릭한 다음 새로 만들기, 프로젝트를 차례로 선택합니다.
새 프로젝트 대화 상자의 WCF 아래에서 상태 시스템 워크플로 서비스 라이브러리 템플릿을 선택합니다.
프로젝트의 이름을 WorkflowServiceTutorial로 지정하고 확인을 클릭합니다.
Visual Studio 2008에서는 WCF 서비스에 사용되는 동일한 스키마를 사용하여 구성 설정을 저장하기 위한 App.config 파일, 계약 정의가 포함된 소스 파일 및 워크플로에 대한 디자이너 코드와 구현 코드를 정의하는 워크플로 클래스 소스 파일을 워크플로 서비스에 대해 생성합니다.
템플릿에서는 두 StateActivity 활동과 함께 상태 시스템 워크플로를 만듭니다. Workflow1InitialState라는 첫 번째 StateActivity 활동에는 EventDrivenActivity 활동이 포함되어 있고 이 활동에는 ReceiveActivity 활동과 그 뒤에 SetStateActivity 활동이 포함되어 있습니다. SetStateActivity 활동의 TargetStateName 속성은 상태 시스템 워크플로의 다른 StateActivity 활동 이름으로 설정됩니다.
ReceiveActivity 형식 자체는 SequenceActivity에서 파생되므로 순차적으로 실행되는 여러 자식 활동을 포함할 수 있습니다. ReceiveActivity 활동의 구현은 표준 WCF 서비스에 대한 작업을 구현하는 것과 유사하지만 메서드 본문에 코드를 구현하는 대신 WF 활동을 통해 작업을 구현합니다.
이 자습서의 ReceiveActivity 활동은 IWorkflow1.cs(또는 Visual Basic 솔루션을 만든 경우 IWorkflow1.vb)에 정의된 몇 가지 새 작업을 구현합니다. 이러한 작업은 요청/응답 작업이므로 클라이언트가 서비스에서 메시지를 다시 받습니다.
이미 제공된 WCF 계약을 사용하기 때문에 이를 워크플로 서비스 제작의 계약 중심 스타일이라고 합니다. 프로그래밍 방식으로 새 계약을 만들려면 How to: Implement a Windows Communication Foundation Contract Operation을 참조하십시오.
인터페이스에서 새 작업을 정의할 것이므로 IWorkflow1.cs(또는 Visual Basic 솔루션을 만든 경우 IWorkflow1.vb)를 열고 기존 인터페이스 정의를 다음 예제의 코드로 바꿉니다.
<ServiceContract()> _ Public Interface IWorkflow1 <OperationContract()> _ Sub StartupService() <OperationContract()> _ Function Add(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Subtract(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Multiply(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Divide(ByVal n1 As Integer) As Integer <OperationContract()> _ Sub ShutdownService() End Interface
[ServiceContract] public interface IWorkflow1 { [OperationContract] void StartupService(); [OperationContract] int Add(int n1); [OperationContract] int Subtract(int n1); [OperationContract] int Multiply(int n1); [OperationContract] int Divide(int n1); [OperationContract] void ShutdownService(); }
서비스 계약을 구현하려면
Workflow Designer가 표시되지 않으면 Workflow1.cs(또는 Visual Basic 솔루션을 만든 경우 Workflow1.vb)를 마우스 오른쪽 단추로 클릭하고 디자이너 보기를 선택하여 디자이너를 엽니다.
StateActivity 활동을 상태 시스템 워크플로로 끈 다음 이름을 OperationsState로 바꿉니다.
stateActivity1의 이름을 FinalState로 바꿉니다.
참고
이 활동의 이름을 바꾸면 이 활동이 워크플로에서 완료됨 상태로 더 이상 표시되지 않으므로 Workflow Designer에서 FinalState를 마우스 오른쪽 단추로 클릭하고 완료됨 상태로 설정을 선택합니다.
Workflow1InitialState라는 StateActivity 활동에서 eventDrivenActivity1을 선택하고 이름을 WaitToStartService로 바꿉니다.
WaitToStartService를 두 번 클릭하여 확장합니다. ReceiveActivity 활동은 WaitToStartService의 자식 활동으로 이미 설정되어 있습니다.
receiveActivity1을 선택하고 속성 창의 ServiceOperationInfo에서 줄임표를 클릭하여 작업 선택 대화 상자를 엽니다.
StartupService를 선택하고 확인을 클릭합니다.
속성 창의 CanCreateInstance 아래에 있는 드롭다운 메뉴에서 True를 선택합니다. 이렇게 하면 StartupService 작업이 호출될 때 워크플로의 인스턴스가 만들어집니다. 이 속성의 기본값은 False로 설정되어 있으며 작업 호출 시 컨텍스트 ID가 클라이언트와 서비스 간에 이미 설정되지 않은 경우 클라이언트에서 다음과 같은 메시지를 받습니다.
There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized.
Workflow1InitialState 디자인 뷰에서 setStateActivity1을 선택합니다.
속성 창에서 TargetStateName 속성의 이름을 stateActivity1에서 OperationsState로 변경합니다.
주 Workflow Designer 뷰로 다시 이동합니다. 이제 Workflow1InitialState와 OperationsState가 연결되어 있습니다.
5개의 EventDrivenActivity 활동을 OperationsState StateActivity 활동으로 끌어서 놓고 WaitToAdd, WaitToSubtract, WaitToMultiply, WaitToDivide 및 WaitToEndService로 이름을 지정합니다.
WaitToAdd를 두 번 클릭하여 확장합니다.
ReceiveActivity 활동을 WaitToAdd 안으로 끌어서 놓습니다.
속성 창의 ServiceOperationInfo에서 줄임표를 클릭하여 작업 선택 대화 상자를 엽니다.
추가를 선택하고 확인을 클릭합니다.
CodeActivity 활동을 ReceiveActivity 활동 안으로 끌어서 놓습니다.
속성 창에서 이벤트 단추를 클릭합니다.
ExecuteCode 이벤트의 텍스트 상자를 두 번 클릭하여 ExecuteCode 이벤트에 대한 이벤트 처리기 메서드를 자동으로 생성합니다.
Workflow1.cs(또는 Visual Basic 솔루션을 만든 경우 Workflow1.vb)를 열어 클래스의 이름을 ServerWorkflow로 바꾸고 템플릿을 통해 만든 returnValue 및 inputValue에 대한 변수 선언을 다음으로 변경합니다.
Public class ServerWorkflow Inherits StateMachineWorkflowActivity Public returnValue As Int32 Public inputValue As Int32 Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) End Sub End Class
public sealed partial class ServerWorkflow : StateMachineWorkflowActivity { public ServerWorkflow() { InitializeComponent(); } public int returnValue = default(int);public int inputValue = default(int); private void codeActivity1_ExecuteCode(object sender, EventArgs e) { } }
ExecuteCode에 대한 이벤트 처리기로 이동합니다.
이벤트 처리기의 본문에서 returnValue에 다음 값을 할당합니다.
Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue += inputValue End Sub
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { returnValue += inputValue; }
OperationsState 디자인 뷰로 돌아가서 ReceiveActivity 활동 추가를 클릭하고 속성 창에서 n1 및 (ReturnValue) 매개 변수를 강조 표시하고 줄임표를 클릭하여 각각 inputValue 및 returnValue에 바인딩합니다. 이렇게 하면 매개 변수를 바인딩할 적절한 멤버 속성을 선택할 수 있는 속성 바인딩 대화 상자가 열립니다.
또한 속성 창에서 CanCreateInstance를 False로 설정된 상태로 두어서 8단계에서 만든 동일한 워크플로 인스턴스를 사용합니다. CanCreateInstance를 True로 설정하면 각 작업 호출에 대한 새 워크플로 인스턴스가 만들어집니다.
WaitToSubtract에서 시작하여 나머지 각 EventDrivenActivity 활동에 대한 ReceiveActivity 및 CodeActivity 활동을 추가합니다. 또한 작업 매개 변수를 전역 변수 inputValue 및 returnValue와 바인딩해야 합니다.
작업을 완료하면 모든 수학 연산에 ReceiveActivity가 연결되고 모든 CodeActivity 활동 이벤트 처리기가 다음과 같이 구현됩니다.
Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue += inputValue End Sub Private Sub codeActivity2_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue -= inputValue End Sub Private Sub codeActivity3_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue *= inputValue End Sub Private Sub codeActivity4_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue /= inputValue End Sub
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { returnValue += inputValue; } private void codeActivity2_ExecuteCode(object sender, EventArgs e) { returnValue -= inputValue; } private void codeActivity3_ExecuteCode(object sender, EventArgs e) { returnValue *= inputValue; } private void codeActivity4_ExecuteCode(object sender, EventArgs e) { returnValue /= inputValue; }
WaitToEndService EventDrivenActivity 활동의 경우 ReceiveActivity 활동을 WaitToEndService 안으로 끌어서 놓습니다.
속성 창의 ServiceOperationInfo 아래에서 줄임표를 클릭하여 작업 선택 대화 상자를 엽니다.
ShutdownService를 선택하고 확인을 클릭합니다.
OperationsState 디자인 뷰에서 SetStateActivity를 WaitToEndService 안의 ReceiveActivity 활동 아래로 끌어서 놓습니다.
SetStateActivity 활동을 선택하고 속성 창의 TargetStateName 아래에 있는 드롭다운 목록에서 FinalState를 선택합니다.
워크플로 서비스를 유지하려면
App.config 파일을 엽니다.
다음과 같이 동작 요소에 SqlWorkflowPersistenceService에 대한 참조를 추가합니다.
<behavior name="WorkflowServiceTutorial.ServerWorkflowBehavior" > <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceCredentials> <windowsAuthentication allowAnonymousLogons="false" includeWindowsGroups="true" /> </serviceCredentials> <workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true"> <services> <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionString="Data Source=localhost\sqlexpress;Initial Catalog=NetFx35Samples_ServiceWorkflowStore;Integrated Security=True;Pooling=False" LoadIntervalSeconds="1" UnLoadOnIdle= "true" /> </services> </workflowRuntime> </behavior>
이 자습서에 사용된 SqlWorkflowPersistenceService는 워크플로 전용 시나리오에 사용할 수 있는 유지 서비스와 같은 형식이므로 워크플로 인스턴스가 유휴 상태일 때 워크플로 서비스 상태 정보가 SQL 데이터베이스에 유지됩니다. 이 시나리오는 기본적으로 .NET Framework 버전 3.5에서 지원되지만 다른 데이터베이스 저장소에 데이터를 저장하기 위해 WorkflowPersistenceService에서 파생시킬 수 있습니다.
또한 워크플로 서비스는 Windows Workflow Foundation의 지속성 기능을 사용할 수 있으므로 영속 서비스와 같이 작업이 완료된 후가 아니라 작업의 구현이 실행되는 도중에 워크플로 서비스 상태 정보를 유지할 수 있습니다.
PersistenceProviderElement의 connectionString 특성 값은 "WorkflowServiceStore"로 설정됩니다. 이것은 SQL 데이터베이스에 연결하려고 할 때 사용되는 연결 문자열의 이름입니다.
참고
이 자습서에서는 NetFx35Samples_ServicesWorkflowStore 데이터베이스를 사용합니다. 데이터베이스를 만들려면 One-Time Setup Procedure for the Windows Communication Foundation Samples에서 Createstores.cmd 스크립트를 실행합니다.
서비스를 빌드하고 실행합니다. WcfSvcHost.exe의 실행이 시작되고 WcfSvcHost.exe에서 서비스를 호스팅합니다. WcfSvcHost.exe는 테스트 목적으로 서비스를 호스팅하는 개발자 도구입니다. 테스트 목적을 위해 순차 워크플로 서비스 라이브러리 및 상태 시스템 워크플로 서비스 라이브러리 템플릿에서 WcfSvcHost.exe 응용 프로그램을 자동으로 사용하여 워크플로 서비스를 호스팅하므로 사용자가 호스트 응용 프로그램을 직접 만들 필요가 없습니다.
설명
워크플로 서비스를 만든 후 작업 2: 워크플로 서비스 클라이언트 만들기에서는 이 워크플로 서비스와 상호 작용할 수 있는 워크플로 서비스 클라이언트를 만드는 방법을 설명합니다.
참고 항목
작업
개념
기타 리소스
Copyright © 2007 by Microsoft Corporation. All rights reserved.