domingo, 24 de octubre de 2010

5. Cuadro resumen de ejemplos por cada actividad

 

 

 

CallExternalMethod

clip_image002

WF_CallExternalMethod

 

El CallExternalMethodActivity es usado para invocar en forma síncrona un método que esta implementado en el local workflow service. Es uno de los primeros mecanismos usados por el workflow para comunicarse con el mundo a través de la actual instancia del workflow.

 

STEP

[ExternalDataExchange]

  1. Definir una interfaz.

  2. Luego implementar los métodos de la interfaz. class:interfaz

  3. Declarar en el host un servicio con EventDataExchangeService

 

Code

clip_image004

WF_Code

ExecuteCode, EventHandler

Esta actividad es una simple forma para ejecutar algún código personalizado que se necesite en algún paso del workflow.

El nombre de la clase asociada con esta actividad es CodeActivity.

 

Compensate

clip_image006

 

 

Tiene como contenedor a CompensateHandlerActivity que se ejecuta si la compensación es necesaria. Esta actividad solamente puede ser adicionada para una actividad que soporte la interfaz ICompensateActivity, actualmente solamente las actividades que soportan esta interfaz son CompensatableTransactionScopeActivity y CompensatableSequenceActivity.

Normalmente la compensación es ejecutada cuando una excepción sin manejar es lanzada en el workflow. Si hay alguna actividad de compensación esta se ejecuta primero que la excepción, y cada una es automáticamente compensada. El CompensateActivity permite manualmente controlar el proceso de compensación. Usando el CompensateActivity, puedes tomar el control incluso del proceso de compensación y directamente ejecutar la lógica de compensación para una actividad.

 

CompensatableSequence

clip_image008

WF_CompensatableSequence

Deshacer un trabajo anterior

No se puede compensar una actividad compuesta como resultado de una excepción

Es equivalente a la actividad de SequenceActivity, pero adicionalmente nos permite manejar  la actividad de Compensate, debe usarse solo si se necesita compensación.

ConditionalActivityGroup

clip_image010

WF_ConditionedActivityGroup

 

Es una actividad compleja e hibrida que exhibe alguno de los comportamientos del WhileActivity y ParallelActivity.

Es una combinación de una característica de ejecución en paralelo con un bucle (loop)

·         Until = false  à todas las actividades canceladas

·         Until = true    à 1…n actividades

 

Delay

clip_image012

WF_Delay

 

El DelayActivity implementa la interfaz IEventActivity. También es clasificada como una actividad basada en eventos. La premisa es simple Delay es como un objeto Timespan, básicamente es el tiempo de espera. Después de pasar el tiempo de duración se dispara un evento para continuar la ejecución del proceso. El tiempo de espera o duración se puede inicializar en la propiedad TimeoutDuration o en evento InitializeTimeoutDuration.

 

EventDriven

clip_image014

 

 

Cada EventDrivenActivity define la ejecución de una ramificación que está esperando por un evento diferente. El EventDrivenActivity es una actividad compuesta y contiene un conjunto de actividades hijas que son ejecutadas cuando el evento es recibido. Solamente una rama del EventDrivenActivity es siempre ejecutada. Cuando una rama recibe su evento, las otras ramas son canceladas.

 

EventHandlingScope

clip_image016

WF_EventHandlingScope

 

Tiene dos elementos SequenceActivity y EventHandlersActivity (es una colección de EventDrivenActivity)

·         CompensatableSequence

·         Sequence

·         TransactionScope

·         CompensatableTransactionScope

·         SynchronizationScope

 

FaultHandler

clip_image018

WF_FaultHandler

 

Una excepción es usada para limpiar el trabajo por una actividad incompleta mientras compensaba, es decir deshacer el trabajo que tuvo que completarse.

El FaultHandlersActivity mantiene una colección de objetos FaultHandlerActivity y es adicionado como un hijo de una actividad compuesta. Cada FaultHandlerActivity corresponde a un simple tipo de Exception y contiene las actividades hijas que tu quieres ejecutar cuando se dispare la excepción, hay que escoger que tipo de excepción FaultType que se va a manejar.

----------------------------------------------------------------------------------------------

El CancellationHandlerActivity es un contenedor que limpia una lógica asociada con una actividad compuesta. Tú puedes adicionar un CancellationHandlerActivity para actividades compuestas para manejar lógica de compensación para las actividades hijas.

Por instancia, el ListenActivity contiene múltiples ramas para las múltiples actividades y todas están activadas esperando por un evento. Una vez que un evento es recibido, las otras actividades no reciben sus eventos ya que son cancelados. Si un CancellationHandlerActivity es adicionado a un ListenActivity, el conjunto de actividades definidas dentro del CancellationHandlerActivity son ejecutadas durante la cancelación.

 

HandleExternalEvent

clip_image020

WF_HandleExternalEvent

 

El HandleExternalEventActivity es usado para recibir un evento desde un servicio local. La forma de definición es muy parecida a la actividad CallExternalMethod con algunos pasos adicionales.

 

STEP

[Serializable]

  1. Definir una class:ExternalDataEventArgs

[ExternalDataExchange]

  1. Definir una interfaz

Definir un evento

event Eventhandler<class> var;

  1. Luego implementar los métodos de la interfaz. class:interfaz

  2. Declarar en el host un servicio con EventDataExchangeService

 

IfElse

clip_image022

WF_IfElse

 

Uno de los grandes avances del workflow es que ellos te permiten declarar un control de flujo de ejecución. Tu desarrollar puede ser distinto, independientes actividades contienen reusable lógica de negocios. El IfElseActivity permite declarar una simple rama de decisión dentro de un workflow.

 

InvokeWebService

clip_image024

WF_InvokeWebService

 

Para usar InvokeWebServiceActivity en un workflow, tú debes adicionar una referencia web al proyecto del workflow. Esto genera una clase proxy que nos permite realizar llamadas a un servicio web. La propiedad de ProxyClass del InvokeWebServiceActivity que contiene el nombre de la clase proxy generada. El MethodNameProperty identifica el método del servicio web que tu deseas invocar. Una vez que el MethodName es seleccionado, el ingreso y salida de parámetros se muestran en la sección de parámetros. Tú puedes enlazar cada para parámetro al workflow o miembro de la actividad.

 

InvokeWorkflow

clip_image026

WF_InvokeWorkflow

 

El InvokeWorkflowActivity permite ejecutar un Nuevo workflow como un paso en el actual workflow. Esto permite rehusar el código similar a las actividades personalizadas, pero en gran escala.

Los pasos para usar esta actividad son bastantes simples:

1.    Jalar y soltar el InvokeWorkflowActivity en la localización deseada en tu workflow.

2.    Poner en la propiedad TargetWorkflow al tipo de workflow que tu deseas ejecutar.

3.    Poner valores para algún parámetro requerido por el TargetWorkflow.

El InvokeWorkflowActivity provee un evento de Invoking en código. Este evento es invocado antes de la creación del nuevo workflow y se tiene la oportunidad para optimizar alguna configuración de las tareas que se requieren antes de que inicie el nuevo workflow.

Un importante aspecto del InvokeWorkflowActivity es que ello se complete tan pronto inicie el nuevo workflow. Ello no espera a que el nuevo workflow se complete. El nuevo workflow se ejecuta asincrónicamente en otro hilo y no se tiene una directa conexión al InvokeWorkflowActivity una vez que es iniciado. Esto significa que InvokeWorkflowActivity es una buena forma de cargar otro workflow de forma autónoma. Un nuevo workflow es cargado,  no hay garantía concerniente al orden de ejecución para los dos workflow.

Desde la nueva instancia del workflow se ejecuta en su propio workflow, no hay forma de recibir parámetros de salida desde la instancia. No hay mecanismos construidos que permitan invocar el workflow para recuperar parámetros de salida desde el workflow de salida. Sin embargo, el workflow invocado puede usar un servicio local para retornar algún dato de salida a la aplicación host.

 

Listen

clip_image028

WF_Listen

 

Tiene como actividad predeterminada el EventDrivenActivity en ambas ramificaciones, por lo que solo espera una actividad Delay o HandleExternalEvent.

Un ListenActivity es una compuesta actividad que permite definir multiples actividades hijas dentro de ella. Asume que cada actividad hija del ListenActivity es una HandleExternalEventActivity que escuche a un diferente evento externo. En este escenario, cada HandleExternalEventActivity es eejcutado al mismo tiempo esperando por un evento. Solamente uno de estos hijos eventualmente recibe su evento y completa su ejecución. La otra actividad fue cancelada por el padre del ListenActivity. Para el evento cancel por el padre ListenActivity, tu defines loas pasos para ser ejecutados cuando el hijo incompleto es cancelado.

Tu no siempre necesitas un cancel handler. Pero si tu actividad requiere algo que limpie cuando ellos son cancelados, un cancel handler es apropiado para definir esta lógica.

 

Parallel

clip_image030

WF_Parallel

Servicio scheduler

Sincronización de hilos (SynchronizationScopeActivity, objeto que  desea bloquear sync-SynchronizationHandlers)

Semáforos

C# AutoResetEvent, manualResetEvent, Mutex, Lock, etc

El ParallelActivity permite la definición de múltiples ramas de actividades hijas con cambio de dirección para cada rama.

Un ParallelActivity permite a organizar 2 o más ramas hijas para su ejecución al mismo tiempo. Cada rama de ejecución es representada por un hijo SequenceActivity. El SequenceActivity es la única actividad que permite ser directamente una actividad hija del ParallelActivity. El SequenceActivity es el contenedor por algún número y tipo de actividades hijas que se quieren ejecutar.

El ParallelActivity no realmente ejecuta múltiples ramas simultáneamente. Cada instancia del workflow ejecuta un simple hilo, así la ejecución paralela de múltiples actividades no es posible.

En lugar de una verdadera ejecución paralela, el ParallelActivity coordina la ejecución de actividades de cada rama, dando a cada SequenceActivity un turno de ejecución. Donde la rama ejecuta una actividad, la ejecución se mueve a la siguiente rama, y así sucesivamente. Todas las ramas tienen un cambio de la ejecución, el proceso inicia de nuevo con la primera rama, ejecutando la siguiente actividad en esta rama.

Cada rama consigue un turno de ejecución, pero no significa que cada rama siempre ejecuta una actividad. Una rama debe contener una actividad que causa la ejecución de que la rama sea retrasada.

Por instancia, una rama debe esperar recibir un evento externo, o debería contener un DelayActivity. En este caso, la ejecución de la rama es pasada y la siguiente rama recibe su turno. Donde la ejecución retorna a la rama que espera, la situación es evaluada nuevamente. Si la rama no demora tanto, toma turno en su ejecución. Si es un estado de espera, la rama pierde el turno de ejecución y la siguiente rama se ejecutara.

La actual secuencia de ejecución de un ParallelActivity no está garantizada. Porque una ejecución de la rama debe ser requerida para esperar por un evento externo o un DelayActivity, la actual secuencia de ejecución es imprevisible.

Cuando se use un ParallelActivity, evite diseñar workflows que confié en un orden particular de ejecución para actividades hijas.

 

Policy

clip_image032

WF_Policy

 

El PolicyActivity permite definir un conjunto de reglas aplicadas a campos o propiedades en un workflow. Cada regla en el RuleSet es descrita con una sintaxis de un if, then, y else que permite configurar las propiedades de Condition, ThenActions, y ElseActions.

Por ejemplo se tiene un PolicyActivity que calcula los totales de las órdenes de venta.

 

SetState

clip_image034

 

 

Donde el StateActivity define el estado, SetStateActivity es usado para la transición a un diferente estado. Se identifica el nuevo estado configurando la propiedad de TargetStateName del SetStateActivity.

El SetStateActivity es usualmente declarado como un hijo de un EventDrivenActivity. El EventDrivenActivity es usado dentro de un StateActivity para esperar a un método externo. El evento dispara adicional procesamiento dentro del estado. Después de la ejecución otras actividades para ejecutarse en el mundo real, el SetStateActivity debe ser declarado como la última actividad en una serie de actividades. Colocar ello en la parte media de una larga secuencia de actividades no es válido.

 

Replicator

clip_image036

WF_Replicator

Secuencia de pasos de un número determinado de veces

UntilCondition

InitialChildData à IList

El ReplicatorActivity es similar a en C# la sentencia foreach, creando una instancia de una actividad hija para cada elemento en una colección de ingreso de datos. Esta actividad es usada cuando tú necesitas manejar datos en el workflow que puedas fácilmente adaptar y responder a la entrada de datos.

 

Sequence

clip_image038

WF_Sequence

 

La SequenceActivity es una compuesta actividad que permite adicionar múltiples actividades hijas que son ejecutadas en un orden definido. Ello es especialmente usado como un hijo de otras actividades que solamente aceptan una simple actividad. Los ejemplos de actividades donde se acepta como actividad hija es el ReplicatorActivity, el WhileActivity y el ParallelActivity.

 

State

clip_image040

 

 

El StateActivity representa un simple estado y es el primer bloque a construir de todas los workflow de maquinas de estados. El StateActivity es usualmente adicionado directamente al inicio del workflow de máquina de estados, pero ello también es adicionado como un hijo de otro StateActivity.

Hay un grupo de actividades que son permitidas como directas actividades hijas  de un StateActivity. La lista de actividades incluidas es EventDrivenActivity, StateInitilizationActivity, StateFinalizationActivity y otro StateActivity.

 

StateInitilization

clip_image042

 

 

El StateInitilizationActivity es una opcional actividad que contiene actividades para ejecutarse donde un estado es ingresado. Tú puedes declarar un máximo de un StateInitializationActivity en un StateActivity.

Cada vez que el workflow cambia de transición de estados, las actividades en el StateInitilizationActivity son ejecutadas antes de alguna otra actividad.

 

StateFinalization

clip_image044

 

 

El StateFinalizationActivity es reciproco al StateInitilizationActivity. Ello es un contenedor para actividades que tu deseas ejecutar antes de la transición a otro estado. Ello es opcional, pero si usas ello, puede ser un máximo de un StateFinalizationActivity por un StateActivity.

 

Suspend

clip_image046

WF_Suspend

 

El SupendActivity detiene la ejecución del workflow, pero no termina permanentemente el workflow. Ello es usado en situaciones donde el workflow tiene un error pero el error es recuperable y el workflow puede ser reiniciado al punto de falla. Posiblemente un parámetro que no es enviado o es incorrecto y ello puede ser fácilmente corregido con una intervención humana. Para reiniciar un workflow suspendido, tu llamas el método Resume del objeto WorkflowInstance.

 

SynchronizationScope

clip_image048

WF_SynchronizationScope

 

El SynchronizationScopeActivity es usado para proveer el acceso controlado a variables o recursos que son compartidos entre paralelas ramas de ejecución. Ello es una compuesta actividad que administra las actividades hijas que tu adicionas a él. Esta actividad trabaja en una similar manera a la sentencia de C# lock. Si dos o más instancias de SynchronizationScopeActivity tienen la misma sincronización, su ejecución es serializada así que las actividades hijas de solamente uno de ellos son ejecutadas alguna vez.

Esta actividad puede ser soportada por ParallelActivity, ContionedActivityGroup y ReplicatorActivity. Si tu usas SynchronizationScopeActivity en cada rama paralela tu puedes serializar la ejecución de actividades hijas con cada SynchronizationScopeActivity. Donde un simple hilo del workflow empieza la ejecución de una rama, ello se asegura que todas las actividades hijas con el SynchronizationScopeActivity  se completen antes de moverse a la siguiente rama de ejecución.

Cada SynchronizationScopeActivity tiene una propiedad SynchronizationHandles. Esta es una colección de manejadores de cadenas que son usadas para la sincronización entre instancias del SynchronizationScopeActivity. Si 2 o más SynchronizationScopeActivity instancias tiene el mismo manejador, sus hijos  se ejecutan de forma serializada.

 

Terminate

clip_image050

WF_Terminate

 

El TerminateActivity inmediatamente detiene la ejecución de una instancia de un workflow. Este es similar al SuspendActivity con una gran diferencia. Si tu usas TerminateActivity, el workflow no puede ser reanudado y no más procesamiento con la instancia del workflow. Por otra parte el SuspendActivity provee para reanudar un workflow. Tú puedes proveer una descripción de mensajes de error con la terminación para configurar la propiedad de Error del TerminateActivity.

 

Throw

clip_image052

WF_Throw

 

El ThrowActivity permite manejar una excepción throw en .NET declarada como un paso de un workflow. Si tú encuentras condiciones de error, permite manejar una excepción desde alguna parte de tu código del workflow. Este código está incluido en el workflow y en algunas actividades personalizadas. Esta actividad te permite hacer lo mismo como actividad del workflow.

Tu deberías usar el ThrowActivity cuando tú quieras manejar una excepción declarativamente en el modelo del workflow que desde código. El resultado final es el mismo si tu usas en C# una sentencia throw para una excepción.

 

TransactionScope

clip_image054

WF_TransactionScope

 

Manejar el concepto de transacción involucra costo en memoria y en persistencia.

El TransactionScopeActivity es usado para definir una simple unidad de trabajo termina o falla completamente.  Esta es una actividad compuesta que permite adicionar actividades hijas. Cuando el TransactionScopeActivity inicia su ejecución, crea una instancia System.Transactions.Transaction para marcar el inicio de una nueva unidad de trabajo. Todas las actividades hijas dentro del TransactionScopeActivity usan la misma transacción durante la ejecución.

Cuando todas las actividades hijas dentro del TransactionScopeActivity se completan, la transacción es cerrada y todos los trabajos pendientes son grabadas. Si una excepción es lanzada por alguna de las actividades hijas, la transacción entera será desechada y todos los trabajos pendientes retornan al estado original.

Si tu workflow incluye un TransactionScopeActivity, tu deberías registrar un servicio de persistencia durante la inicialización del runtime del workflow.

 

CompensatableTransactionScope

clip_image056

WF_CompensatableTransactionScope

 

Permite manejar el concepto para Base de datos:

·         Atomic

·         Consistent

·         Isolated

·         Durable

La compensación es deshacer un trabajo que fue completado pero es parte de un largo workflow que falla. Si una actividad en un workflow fue completada exitosamente, pero el workflow después falla en un largo workflow donde mantener una transacción para garantizar la consistencia de los datos no es factible, debido al tiempo y/o complejidad del proceso, o donde solo se necesite compensación.

El CompensatableTransactionScopeActivity es similar al TransactionScopeActivity, pero también soporta compensación. Provee una transacción para sus actividades hijas y graba la transacción cuando las actividades terminan. También permite declarar un conjunto de actividades para ejecutar si la compensación después es necesaria.

En cierta manera, el CompensatableTransactionScopeActivity es una versión del SequenceActivity que soporta la compensación. El SequenceActivity, permite declarar en una lista ordenada de actividades hijas. Pero también soporta la declaración de actividades que son ejecutadas si la actividad requiere compensación.

 

Las actividades que son incluidas en el trabajo real del método del servicio web son WebServiceInputActivity y WebServiceOutputActivity, pero ambas actividades no pueden ser ejecutadas en una única instancia del workflow. Si necesitamos retornar una falla del servicio web, debemos usar el WebServiceFaultActivity.

Loading the ManualWorkflowSchedulerService

El scheduler por defecto usado por el workflow runtime para las ejecuciones de los workflows es asíncrono en su propio hilo. El ManualWorkflowShedulerService (en el espacio de nombres es System.Workflow.Runtime.Hosting) es un alternativo servicio de cronograma que ejecuta workflow asíncronos en la llamado de su hilo.

Para cargar este servicio en el Web.config para que el workflow runtime ejecute el workflow usando el hilo original desde el servicio web de la petición del ASP.NET. Esto ayuda a controlar el número de hilos que son usados a la vez y también ejecutar el workflow síncrono al llamado de su hilo.

Es importante setear la propiedad UseActiveTimers del servicio a true durante la construcción. Si está cargando este servicio vía Web.config, necesitas setear la propiedad a true. Si tu no seteas la propiedad a true, alguna instancia del DelayActivity no empieza automáticamente después de que el tiempo haya expirado del DelayActivity. Para configurar esta propiedad a true, el servicio usa un hilo separado para detectar la expiración de un delay y automáticamente reinicia la instancia del workflow.

Loading the WorkflowWebHostingModule

El WorkflowWebHostingModule (en el espacio de nombre System.Workflow.Runtime.Hosting) es un ASP.NET modulo HTTP que es también incluido en el web.config generado. Los HTTP módulos son parte de la petición del ASP.NET y son llamados con cada petición y respuesta.

El propósito de este particular modulo es para encaminar una petición en un servicio web para la correcta instancia del workflow. Par lograr esto, ASP.NET cookies son usados. Cada cookie contiene el instancia ID (Guid) que identifica la instancia del workflow usado por el cliente. Cuando este modulo HTTP es usado, los clientes del servicio web deben soportar cookies

Loading a Persistence Service

Aunque no es estricto requerimiento (esto no es automáticamente añadido al web.config), un servicio de persistencia debería generalmente cargar cuando el workflow hosting en el ambiente ASP.NET. El SqlWorkflowPersistenceService puede ser usado para persistir en una base de datos SQL Server, o desarrollar nuestro propio servicio.

La persistencia es importante especialmente para ASP.NET ya que reduce el número de workflow en memoria. Cuando el workflow está inactivo o es suspendido, no necesita mantenerse en memoria. Pero tú no puedes removerlo de la memoria al menos que persista. Por consiguiente el ser servicio de persistencia provee un mecanismo que permite a los workflow inactivos ser removidos de la memoria.

Developing a Web Service Workflow

La propiedad IsActivating por defecto es false, pero debe ser seteado a true. El valor true indica que tu recibes una especifica petición indicando que debería activarse una nueva instancia del workflow. Tu puedes setear solamente IsActivating a true para el primer WebServiceInputActivity en un workflow.

Luego de la publicación del workflow como servicio web la clase generada, deriva de la clase WorkflowWebService (en el espacio de nombres System.Workflow.Activities). Esta clase es la clase base para todos los workflow de servicio web. El Web.Config generado contiene lo mínimo para poder probar nuestro workflow vía servicio web. Se debe modificar el Web.config, primero adicionando una entrada para cargar el SqlWorkflowPersistenceService para proveer el servicio de persistencia. Es una buena práctica configurar el servicio de persistencia cuando se expone workflow como servicios web, especialmente si se tiene actividades que inactivan el workflow.

También generalmente se remueve la entrada DefaultWorkflowCommitWorkBatchService. Este es el default servicio consignación para el trabajo (transacción) que es automáticamente cargado por el workflow runtime, sino hay un trabajo de consignación para el servicio especificado. Esto no daña la entrada del servicio, pero no adiciona algún valor. Finalmente se debe añadir una entrada a la propiedad UseActiveTimers a true.

 

<configuration>

  ...

  <WorkflowRuntime Name="WorkflowServiceContainer">

    <Services>

            

      <add type="System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" UseActiveTimers="true"/>

      <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" UnloadOnIdle="true" LoadIntervalSeconds="5" ConnectionString="Data Source=PCUSER;Initial Catalog=WorkflowStore;Integrated Security=True" />

            

    </Services>

  </WorkflowRuntime>

  ...

  <system.web>

    <httpModules>

              

        <add type="System.Workflow.Runtime.Hosting.WorkflowWebHostingModule, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="WorkflowHost"/>

              

    </httpModules>

  </system.web>

</configuration>

 

Cuando tú publicas el servicio web usa por defecto el espacio de nombres http://tempuri.org/. Se recomienda cambiar el espacio de nombre por defecto y asegurar que tu web services es único.

Sin embargo cuando publicas el workflow como servicio web, no provee una forma de cambiar el espacio de nombres por defecto.

Con respecto a este problema identificado, no hay alguna recomendación con respecto a este punto. Ello requiere modificar el registro para grabarlo en el los archivos generados temporales en el directorio temporal, manualmente debe ser modificado, e incluso en tu proyecto del servicio web. Si tu intentas ejecutar el workflow otra vez, se enviara el siguiente error:

--------------------------------------------------------------------------------------------

System.InvalidOperationException:

Workflow with id &quot;03ff8f3f-5925-4925-932f-ab016c268897&quot;

not found in state persistence store.

--------------------------------------------------------------------------------------------

Recordemos que el modulo HTTP WorkflowWebHostingModule que es quien carga las comunicaciones de los clientes de los servicios web usan cookies.  Ello pasa a un temporal cookie que contiene las instancias del workflow. El cookie es nombrado WF_WorkflowInstanceId y es seteado para expirar la actual sesión.

Cuando tu ejecutas un servicio web otra vez usando la pagina de prueba, el existente cookie es retornado al servicio y es nuevamente cargada la anterior versión del workflow. Desde entonces el workflow se completa cuando finaliza la primera operación de división, la instancia de petición no existe la base de datos persistente. El resultado es un error.

Un real cliente del servicio web determina qué hacer con este cookie. En particular un servicio web, el workflow termina tan pronto como el método retorna del servicio web, y no se necesita grabar la cookie. Sin embargo el cliente debe usar la cookie si está corriendo un gran workflow sea invocado. Si múltiples llamadas son hechas al workflow para la misma instancia, la cookie debería ser usada para identificar la existente instancia el workflow.

Si tú quieres conseguir que funcione en los clientes del servicio web sin desarrollar, tu deberías cerrar todos los browser para remover las sesiones de cookies. Si tú inicias un nuevo browser se iniciara sin problemas.

El WorkflowWebHostingModule provee soporte basado en cookies que identifiques un ID de la instancia del workflow. Para pasar este ID entre el cliente y el workflow runtime, el cliente puede invocar múltiples métodos de un servicio web de la misma instancia del workflow. Cuando tú adicionas persistencia para la mezcla, tú tienes la habilidad de descargar los workflows inactivos de la memoria mientras esperan por la siguiente llamada al servicio web.

 

WebServiceInput

clip_image058

WF_WebService

WebServiceOutput

clip_image060

WebServiceFault

clip_image062

 

WebServiceInput

Mientras el InvokeWebServiceActivity es usado para invocar un servicio web desde un workflow. El WebServiceInputActivity hace lo opuesto. Ello expone el workflow como método de un servicio web. Esto permite a los clientes llamar directamente al servicio web como si ellos estuvieran invocando cualquier servicio web.

El WebServiceInputActivity maneja la recepción de una llamada inicial de un servicio web. Esta actividad trabaja conjuntamente con el WebServiceOutputActivity y el WebServiceFaultActivity.

El WebServiceInputActivity implementa la interfaz IEventActivity. Por esto son considerados como una actividad event-driven.

 

WebServiceOutput

El WebServiceOutputActivity es usado con WebServiceInputActivity expone un workflow como servicio web para los clientes. El WebServiceOutputActivity es responsable de enviar una respuesta al servicio web del cliente. Solamente el valido en un workflow que también incluya el WebServiceInputActivity.

Las dos actividades actuan como un apoya-libros. Tú inicias con el WebServiceInputActivity, seguido de algunas otras actividades que se necesitan parta el proceso de respuesta del servicio web. Cuando tú estás listo para retornar una respuesta al servicio web cliente, tu incluyes el WebServiceOutputActivity.

 

WebServiceFault

El WebServiceFaultActivity es usado cuando tú necesitas enviar un error al servicio web cliente indicando una condición de error. Tú puedes solamente enviar una respuesta a un cliente, usando cada WebServiceFaultActivity para indicar el error, o el WebServiceOutputActivity para enviar una respuesta. Tú deberías típicamente hacer tu decisión de respuesta en el cuerpo del workflow y entonces ejecutar solamente una de estas actividades.

 

Using Workflow from ASP.NET

Es necesario cargar el workflow runtime dentro del ambiente hosting del ASP.NET y entonces referenciar ello cuando tú quieras iniciar un workflow. Esto se logra con un conjunto de entradas en el Web.config y poco código.

Es importante cargar el ManualWorkflowSchedulerService dentro del runtime cuando se ejecuta el workflow desde ASP.NET. Cuando este servicio es cargado, cada ejecución es síncrona al actual hilo de ASP.NET. Si tú no cargas este servicio, los workflows son ejecutados asíncronamente usando administración de hilos por el workflow runtime.

Si tú no usas servicios web, tú no necesitas cargar el WorkflowWebHostingModule. Este modulo HTTP pasa una cookie que identifica la instancia del workflow ID. Estas líneas deben ser removidas del Web.config:

 

   <httpModules>

    

     <add type="System.Workflow.Runtime.Hosting.WorkflowWebHostingModule, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="WorkflowHost"/>

    

    </httpModules>

   

 

While

clip_image064

WF_While

 

El WhileActivity provee la habilidad para repetidamente ejecutar una actividad mientras la condición es true.

El WhileActivity repetidamente ejecuta una simple actividad hija mientras la condición sea true. La condición puede ser expresada como un código o conjunto de condiciones. La condición es verificada previamente el inicio de la iteración, así es posible que las actividades hijas no sean ejecutadas si la condición es false.

 

Una de las mejoras en el .NET 3.5 es la integración de WCF y WWF, workflow services son los más visibles resultados de este trabajo. Workflow services son servicios WCF que se han implementado como workflows. Tú puedes exponer workflows directamente como servicios WCF sin la necesidad de escribir código adicional. La integración de WCF/WF también provee la habilidad de invocar WCF declarativamente desde el mismo código.

El request/response message exchange y el patrón one-way message es soportado por WCF pero también es soportado por workflow services. Sin embargo el patrón dúplex  disponible para nativos servicios WCF no es soportado por workflow services.

 

.NET 3.5 se adicionaron nuevas actividades estándar que provean soporte a WCF dentro del workflow. El ReceiveActivity es usado para exponer un workflow como una operación de servicio WCF. El SendActivity provee la habilidad para invocar un servicio WCF dentro del workflow. Amabas actividades están en el espacio de nombres System.Workflow.Activities, pero estos están empaquetados en el nuevo ensamblado Workflow.Activities. Si la intención es usar estas actividades tú necesitas adicionar una referencia a este nuevo ensamblado.

 

ReceiveActivity

clip_image066

WF_ReceiveActivity

 

Cada ReceiveActivity está asociada con un simple servicio que tu deseas implementar con el workflow. ReceiveActivity implementa la interfaz IEvenActivity, siendo bueno como primer hijo de un EventDrivenActivity. Cuando es usado en un workflow de máquina de estados, el ReceiveActivity típicamente sera usado con un EventDrivenActivity para empezar la ejecución cuando un evento es recibido. En este caso, el evento actualmente es invocado de la operación de un servicio WCF. Pero el ReceiveActivity puede también ser usado en un workflow secuencial y fuera de un EventDrivenActivity.

Si el contrato del servicio define múltiples operaciones de servicio, tú necesitaras usar un diferente ReceiveActivity para implementar cada uno. Tú no estás obligado a proveer una implementación para todas las operaciones que están definidas en el contrato. Sin embargo si tu no haces esto tu recibirás un warning cuando construyas un workflow. Desde la operación tiene que ser definida a la vez como parte de un mismo contrato de servicio, es una buena política para implementarse. Los consumidores de un contrato de servicio tienen la esperanza que todas las operaciones definidas en el contrato están disponibles para usarse.

El ReceiveActivity es una actividad compuesta (derivada de SequenceActivity) permitiendo adicionar actividades hijas que son ejecutadas cuando la operación es invocada. Una instancia de un ReceiveActivity maneja el completar del servicio. Si el patrón de request/response message exchange es usado para una operación del servicio, la respuesta es enviada por el ReceiveActivity antes de ser completada. Después de esto alguna actividad hija será ejecutada para optimizar el trabajo necesario para implementar la operación. Si la operación usa el patrón one-way, no se envió la respuesta.

El contrato y la operación del servicio son identificados para configurar la propiedad ServiceOprationInfo del ReceiveActivity. Esta propiedad puede ser seteada en código, pero el diseñador del WF incluye una forma fácil de importar un existente contrato o crear uno nuevo.

Otra notable propiedad es el CanCreateInstance. Esta propiedad determina que cuando llames una operación del servicio sea capaz de crear una nueva instancia del workflow. Si es true, la nueva instancia del workflow es creado cuando el cliente llama la operación del servicio. Una excepción a esta regla es cuando la aplicación cliente está participando a una activa conversación con la instancia del workflow. Si el valor es false significa que la instancia del workflow debe ser creada por una diferente operación de servicio o creada en código usando el método CreateWorkflow del workflow runtime.

El ReceiveActivity provee un evento de OperationValidation que se maneja en código. Este evento es disparado cuando la actividad recibe un mensaje pero antes de realizar algún procesamiento. Esta es la oportunidad para rechazar el servicio como por ejemplo si no se pasa algún criterio de seguridad. Los argumentos para este evento (OperationValidationEventArgs) tiene una propiedad Isvalid que seteandose en false causa que la operación del servicio sea rechazada.

 

App.config

    services

        service  name/behaviorConfiguration

        host

            baseAndresses

        endPoint  wsHttpContextBinding

        endpoint  mexHttpBinding

    behaviors

        serviceBehaviors

            behavior

                serviceMetadata

                serviceDebug

                serviceCredentials

 

%ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\WcfSvcHost.exe /service:" WF_ReceiveActivity.dll" /config:" WF_ReceiveActivity.dll.config" /client:"WcfTestClient.exe"

 

clip_image068

 

SendActivity

clip_image070

WF_SendActivity

 

SendActivity es usado para invocar un servicio WCF desde el workflow. Esta actividad es derivada la clase de la actividad base y no soporta actividades hijas. Conceptualmente, es el opuesto del ReceiveActivity invocando un servicio en vez de proveer uno.

En realidad el ReceiveActivity y el SendActivity están asociados con una simple operación de un simple contrato de servicio. Tú seleccionas operaciones y contratos de servicio para configurar la propiedad ServiceOperationinfo. En el diseñador se tiene un asistente que permite importar un servicio y seleccionar una operación. Sin embargo en diferencia del ReceiveActivity, tú no puedes crear un nuevo contrato de servicio usando SendActivity. Solamente la forma de usar esta actividad es importar un contrato de servicio existente desde una referencia a un ensamblado. Esto se comporta para este caso como un consumidor de un servicio y no como un proveedor de un servicio.

SendActivity requiere la dirección del servidor de intercambio a ser usado, conocido en WCF como endpoint. Esta información debe estar definida en el archivo de configuración de la aplicación y entonces referenciamos este endpoint en la propiedad ChannelToken del SendActivity.

La propiedad de ChannelToken es una instancia de la clase Channeltoken y contiene 3 propiedades que deberían ser seteadas correctamente. La propiedad EndPoint debe tener el nombre del endpoint configurado para la aplicación host.

 

Workflow Serialization and Marshup

Se tiene ejemplos de code-only (código solamente), code-separation (código separado) y code authoring modes (modo de código autorizado)

Para compilar un workflow marshup para un nuevo asembly usando la clase WorkflowCompiler y la línea de comando wfc.exe del compilador del workflow.

Uno de los principales beneficios de aplicaciones con workflow es que mantiene separado el modelo del workflow y tu lógica de negocio.

WF soporta algunos modos escritos que tú puedes usar cuando defines el modelo del workflow. Tenemos el modelo de workflow por código basado en los objetos del modelo del WF y definiendo archivos XML.

Code-Only Authoring Mode

El Code-Only Authoring Mode (modo escrito de código) solamente genera un archivo que contiene el modelo del workflow.

Si el nombre del workflow es Workflow1, genera el archivo Workflow1.cs es donde se tiene los manejadores de eventos y otra lógica de negocio. El segundo archivo es Workflow1.Designer.cs contiene el modelo del workflow. Desde el diseñador del workflow adicionas o remueves código de este archivo, fuera de limitaciones y no puede ser manualmente modificado.

Si el workflow usa reglas o usa condiciones, genera un archivo Workflow1.rules. Este archivo contiene una versión serializada de las reglas de definición para el workflow. Este archivo es cargado por el workflow runtime desde el recurso embebido dentro del asembly

Todos los archivos hacen la definición del workflow son contenidos en un simple proyecto que son compilados dentro de un binario. El runtime lo compila en un .NET workflow Type y es usado para crear una instancia.

La principal desventaja del modo escrito es que está limitada la habilidad para modificar el modelo del workflow. Tú puedes utilizar actualizaciones dinámicas, pero realmente solo hay una forma de modificar un modelo del workflow abriendo Visual Studio, modificando el modelo del diseñador del workflow, y entonces reconstruir el proyecto.

Code-Separation Authoring Mode

WF también soporta el modo escrito llamado de código separado (code-separation). En este modo, el modelo del workflow es mantenido por el diseñador del workflow en un archivo separado con extensión .xoml. Este es un archivo XML que declara el modelo del workflow usando XAML (Extensible Application Markup Language). XAML es un formato de serialización que especifica instancias de objetos como elementos XML y propiedades de estos objetos como atributos XML.

El segundo archivo creado es para algún evento de los manejadores de eventos y otra lógica del negocio. Esta es una referencia como code-beside (código junto). Si tu creas un nuevo workflow de nombre Workflow1, se crean dos archivos de nombres Workflow1.xoml y Workflow1.xoml.cs. Y si tú has creado reglas, ellos son mantenidos en un archivo separado Workflow1.rules como el modo escrito de código solamente (WPF usa archivos con extensión .xaml por eso WF adopto la extensión .xoml).

El modo de escritura de code-separation (código separado) tiene las mismas ventajas que el modo de código solamente (experiencia familiar de desarrollo, fácil uso, y eficiente). La primera ventaja del código separado es el potencial que ofrece. Declarando el modelo del workflow como enriquecido es mucho más accesible al desarrollo y herramienta de aplicación. Por instancia, tu puedes desarrollar una herramienta que modifique el modelo del workflow para deserializar y serializar el archivo markup. Después de modificar el markup, tú tienes que recompilar los markup dentro del workflow Type (usando el comando del workflow compiler o las clases WorkflowCompiler). Esta capacidad es importante que tú desees proveer al usuario final la posibilidad de modificar el workflow, tal vez por hosting del diseñador del workflow dentro de tu aplicación. Tú ciertamente puedes actualizar el modelo del workflow usando el objeto de modelos del workflow. Pero es fácil de hacer cuando ello esta descrito en el markup en vez del código.

No-Code Authoring Mode

El final modo de escribir es llamado no-code (nada de código). Como se podría deducir del nombre es que no hay un archivo de code-beside. La definición entera del modelo del workflow es hecha usando markup (XAML).

No hay un template dentro del Visual Studio. El Visual Studio no provee directamente soporte para crear archivos .xoml sin un archivo de código. El modo de escribir no-code es principalmente diseñado para facilitar un workflow sin código, tú puedes borrar el archivo de code-beside (ej. Workflow1.xoml.cs). Tu puedes jalar y soltar actividades dentro del diseñador del workflow y setear propiedades de actividades de forma normal.

Sin embargo tú no puedes adicionar actividades que requieran el archivo e code-beside adicionado automáticamente al proyecto para proveer el manejador de eventos de ejecución. Cuando esto ocurra, tú tienes el modo anterior de code-separation.

El workflow markup puede solamente crear instancias de tipos que tienen que ser definidos, implementados, y compilados. Tú no puedes adicionar un nuevo ingreso o propiedad de salida.

Están construidos por bloques que después son ensamblados usando markup. Incluyendo actividades personalizadas y clases personalizadas de workflow. Las actividades personalizadas son usadas para encapsula en tareas especificas de lógica de negocio y expone public, bindable, dependency properties que provee acceso para entradas y salidas de valores. Las clases personalizadas del workflow proveen propiedades de ingreso y salida, que son requeridos por una particular tarea del workflow. Definiendo propiedades en una clase del workflow personalizada son requeridas si tu quieres pasar parámetros de ingreso a un workflow no-code durante la creación del workflow.

La segunda tarea es para el asembly del workflow usando la librería de tipos personalizados y tipos estándar. En vez de construir una clase estándar del workflow, tú puedes usar una clase personalizada del workflow como un Type base del workflow. Para hacer esto tú provees acceso a la propiedades y otros miembros que tu defines en tu clase personalizada. Tu puedes entonces defines el modelo del workflow para declarar instancias de actividades estándar y actividades personalizadas. Propiedades de esta actividad pueden ser seteados directamente o comprometido a otras actividades o clases de workflow. El archivo markup (.xoml) y archivos .rules son accedidos directamente por el workflow runtime. Esta es la mayor diferencia de otros modos escritos, que crea una instancia del workflow desde un compilado Type

Una de sus principales ventajas es su flexibilidad del workflow no-code, además de actualizar el modelo si reconstruir los tipos del workflow que son referenciados por el modelo. En resumen, el workflow sin código son muy dinámicos y fáciles de modificar.

Sin embargo los workflow no-code requieren planeamiento y disciplina. Tú no puedes adicionar miembros o adicionar nuevo código de tipos de workflow que tú referencies, en lugar de esto aumenta tu lógica de negocio en actividades personalizadas o clases base de workflow. Coloque tu lógica de negocio para actividades personalizadas es actualmente recomendada al desarrollo del workflow, pero requiere adicional planeamiento.

Si tu estas desarrollando aplicaciones con alto rendimiento que ejecuta grandes workflows, tu deberías necesitar considerar flexible al cambio vs rendimiento. Carga y parsea un modelo del workflow desde XAML no es eficiente como cargar un Type compilado. Si el rendimiento es un asunto. Tú necesitas pre compilar tus archivos markup y entonces cargar ello como un Type compilado.

 

No hay comentarios: