Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En esta tarea se crea un servicio básico de flujo de trabajo de equipo de estado que implementa un contrato Windows Communication Foundation (WCF) y conserva la información de estado del servicio en una base de datos SQL. Hará esto mediante el estilo de creación de contrato primero.
Nota
Este servicio de flujo de trabajo se usará en los ejercicios restantes de este tutorial.
Nota
Cuando se usa el diseñador de flujo de trabajo de Visual Studio para crear o administrar servicios de flujo de trabajo, a veces se generan errores de validación falsos. Si puede generar correctamente su proyecto, omita los errores de validación.
Establecimiento del servicio de flujo de trabajo y definición del contrato
Abra Visual Studio 2008, haga clic en Archivo y seleccione Nuevo y, a continuación, Proyecto.
En el cuadro de diálogo Nuevo proyecto, en WCF, seleccione la plantilla Biblioteca de servicio de flujo de trabajo de equipo de estado.
Denomine a su proyecto WorkflowServiceTutorial y haga clic en Aceptar.
Visual Studio 2008 genera los archivos siguientes para su servicio de flujo de trabajo: un archivo App.config para almacenar la configuración mediante el mismo esquema que se utiliza para los servicios WCF, un archivo de origen que contiene una definición de contrato, y los archivos de origen de clase de flujo de trabajo que definen el código de diseñador y el código de implementación para su flujo de trabajo.
La plantilla crea un flujo de trabajo de equipo de estado con dos actividades StateActivity. La primera actividad StateActivity, denominada Workflow1InitialState, contiene una actividad EventDrivenActivity que contiene una actividad ReceiveActivity seguida por una actividad SetStateActivity. La actividad SetStateActivity tiene su propiedad TargetStateName establecida en el nombre de la otra actividad StateActivity en el flujo de trabajo de equipo de estado.
El propio tipo ReceiveActivity deriva de SequenceActivity y, como tal, puede contener varias actividades secundarias que se ejecutan en orden secuencial. La implementación de una actividad ReceiveActivity es análoga a la implementación de una operación en un servicio WCF estándar, pero en lugar de implementar su código en el cuerpo de un método, implementa las acciones a través de actividades WF.
Las actividades ReceiveActivity en este tutorial implementan varias nuevas operaciones definidas en IWorkflow1.cs (o IWorkflow1.vb si crea una solución Visual Basic). Éstas son operaciones de solicitud/respuesta; por consiguiente, el cliente recibirá de vuelta un mensaje del servicio.
Dado que está utilizando un contrato WCF que ya se proporciona, se conoce como un estilo de contrato primero de creación de un servicio de flujo de trabajo. Si desea crear mediante programación un nuevo contrato, consulte How to: Implement a Windows Communication Foundation Contract Operation.
Dado que va a definir nuevas operaciones en su interfaz, abra IWorkflow1.cs (o IWorkflow1.vb si crea una solución Visual Basic) y reemplace la definición de interfaz existente con código del ejemplo siguiente:
<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(); }
Implementación del contrato de servicio
Si el diseñador de flujo de trabajo no es visible, abra el diseñador haciendo clic con el botón secundario del mouse en Workflow1.cs (o Workflow1.vb si crea una solución Visual Basic) y seleccione Diseñador devistas.
Arrastre una actividad StateActivity a su flujo de trabajo de equipo de estado. Cámbiele el nombre a OperationsState.
Cambie el nombre de stateActivity1 a FinalState.
Nota
Al cambiar el nombre de esta actividad, ya no se marca como el estado completado para el flujo de trabajo; por consiguiente, haga clic con el botón secundario en FinalState en el diseñador de flujo de trabajo y seleccione Establecer como estado completado.
En la actividad StateActivity denominada Workflow1InitialState, seleccione eventDrivenActivity1 y cámbiele el nombre a WaitToStartService.
Haga doble clic en WaitToStartService para expandirlo. Una actividad ReceiveActivity ya se ha establecido como una actividad secundaria de WaitToStartService.
Seleccione receiveActivity1 y en el panel Propiedades, en ServiceOperationInfo, haga clic en los puntos suspensivos para abrir el cuadro de diálogo Seleccionaroperación.
Seleccione StartupService y, a continuación, haga clic en Aceptar.
En el panel Propiedades, en CanCreateInstance, seleccione True en el menú desplegable. Esto significa que se creará una instancia del flujo de trabajo cuando se invoque la operación StartupService. El valor predeterminado para esta propiedad está establecido en False y si un id. de contexto aún no se hubiera establecido entre el cliente y el servicio al invocarse la operación, entonces el cliente recibiría el mensaje siguiente:
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.En la vista de diseño Workflow1InitialState, seleccione setStateActivity1.
En el panel Propiedades, cambie el nombre para la propiedad TargetStateName de stateActivity1 a OperationsState.
Vuelva a la vista de diseñador de flujo de trabajo principal. Debería haber ahora una conexión entre Workflow1InitialState y OperationsState.
Arrastre y coloque cinco actividades EventDrivenActivity en la actividad StateActivity OperationsState y denomínelos WaitToAdd, WaitToSubtract, WaitToMultiply, WaitToDivide y WaitToEndService.
Haga doble clic en WaitToAdd para expandirlo.
Arrastre y coloque una actividad ReceiveActivity dentro de WaitToAdd.
En el panel Propiedades, en ServiceOperationInfo, haga clic en los puntos suspensivos para abrir el cuadro de diálogo Seleccionar operación.
Seleccione Agregar y haga clic en Aceptar.
Arrastre y coloque una actividad CodeActivity dentro de la actividad ReceiveActivity.
En el panel Propiedades, haga clic en el botón Eventos.
Haga doble clic en el cuadro de texto para que el evento ExecuteCode genere automáticamente un método de control de eventos para el evento ExecuteCode.
Abra Workflow1.cs (o Workflow1.vb si crea una solución de Visual Basic), cambie el nombre de la clase a ServerWorkflow y cambie las declaraciones de variable para returnValue e inputValue, que se crearon por la plantilla, a lo siguiente:
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 Classpublic 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) { } }Vaya al controlador de eventos para ExecuteCode.
En el cuerpo del controlador de eventos, asigne el valor siguiente a returnValue:
Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue += inputValue End Subprivate void codeActivity1_ExecuteCode(object sender, EventArgs e) { returnValue += inputValue; }Vuelva a la vista de diseñador OperationsState, haga clic en la actividad Add ReceiveActivity, y en el panel Propiedades, enlace los parámetros n1 y (ReturnValue) a inputValue y returnValue, respectivamente, resaltando cualquiera de los dos parámetros y haciendo clic en los puntos suspensivos. Esta acción abrirá el cuadro de diálogo de enlace de propiedad, donde puede seleccionar la propiedad miembro adecuada a la que enlazar un parámetro.
Además, en el panel Propiedades, deje CanCreateInstance establecido en False para seguir utilizando esa misma instancia de flujo de trabajo que se creó en el paso 8. Si no, al establecer CanCreateInstance en True, se creará una nueva instancia de flujo de trabajo para cada invocación de operación.
Agregue las actividades ReceiveActivity y CodeActivity para cada una de las actividades EventDrivenActivity restantes que se inician con WaitToSubtract. Recuerde también enlazar los parámetros de operación con las variables globales inputValue y returnValue.
Al finalizar, cada operación matemática debería tener un ReceiveActivity asociado y todos controladores de evento de actividad CodeActivity deberían implementarse de la manera siguiente:
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 Subprivate 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; }Para la actividad WaitToEndService EventDrivenActivity, arrastre y coloque una actividad ReceiveActivity dentro de WaitToEndService.
En el panel Propiedades, en ServiceOperationInfo, haga clic en los puntos suspensivos para abrir el cuadro de diálogo Seleccionar operación.
Seleccione ShutdownService y haga clic en Aceptar.
En la vista de diseño OperationsState, arrastre y coloque SetStateActivity dentro de WaitToEndService en la actividad ReceiveActivity.
Seleccione la actividad SetStateActivity y en el panel Propiedades, en TargetStateName, seleccione FinalState en la lista desplegable.
Conservación de su servicio de flujo de trabajo
Abra el archivo App.config.
Agregue una referencia a SqlWorkflowPersistenceService en su elemento de comportamiento como se muestra.
<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>El SqlWorkflowPersistenceService utilizado en este tutorial es el mismo tipo de servicio de persistencia que se puede utilizar en escenarios de solo flujo de trabajo, lo que significa que su información de estado de servicio de flujo de trabajo se conservará en una base de datos SQL en cualquier momento en que la instancia de flujo de trabajo esté inactiva. Este escenario se admite de forma predeterminada en .NET Framework versión 3.5, pero puede derivar de WorkflowPersistenceService para conservar los datos en otros almacenes de base de datos.
También, debido a que el servicio del flujo de trabajo puede utilizar la funcionalidad de persistencia de Windows Workflow Foundation, la información de estado del servicio de flujo de trabajo se puede conservar durante la ejecución de la implementación de una operación, en lugar de después de su finalización como en un servicio duradero.
El valor de atributo connectionString en el PersistenceProviderElement está establecido en "WorkflowServiceStore". Éste es el nombre de la cadena de conexión que se utilizará al intentar conectarse a su base de datos SQL.
Nota
Este tutorial utiliza la base de datos NetFx35Samples_ServicesWorkflowStore. Para crear la base de datos, ejecute el script Createstores.cmd desde One-Time Setup Procedure for the Windows Communication Foundation Samples.
Genere su servicio y ejecútelo. WcfSvcHost.exe empezará a ejecutarse y hospedará a su servicio. WcfSvcHost.exe es una herramienta de desarrollo que hospeda servicios para propósitos de prueba. Para propósitos de prueba, las plantillas Biblioteca de servicio de flujo de trabajo secuencial y Biblioteca de servicio de flujo de trabajo de equipo de estado utilizan automáticamente la aplicación WcfSvcHost.exe para hospedar su servicio de flujo de trabajo, así que no tiene que crear una aplicación host usted mismo.
Comentarios
Después de haber terminado de crear el servicio de flujo de trabajo, en Tarea 2: Creación de un cliente de servicio de flujo de trabajo se describe cómo crear un cliente de servicio de flujo de trabajo que podrá interactuar con este servicio de flujo de trabajo.
Consulte también
Tareas
Tarea 2: Creación de un cliente de servicio de flujo de trabajo
Conceptos
Cómo configurar un servicio de flujo de trabajo
Otros recursos
Ejercicio 1: Creación de un servicio de flujo de trabajo básico
Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.