Compartir a través de


Adición de flexibilidad a los flujos de trabajo de SharePoint 2010 mediante el motor de reglas de Windows Workflow Foundation

Resumen: obtenga información sobre capacidades y ventajas del motor de reglas de Windows Workflow Foundation que pueden ayudarle a automatizar la lógica de negocios y los procesos de flujos de trabajo en aplicaciones de Microsoft SharePoint 2010. Sepa cómo y cuándo usar el motor de reglas para escenarios de flujo de trabajo de SharePoint simples o más complejos.

Última modificación: lunes, 25 de julio de 2011

Hace referencia a: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

En este artículo
Flujos de trabajo de SharePoint y el motor de reglas de Windows Workflow Foundation
Objetivo: Separar la lógica de negocios de la lógica de procesamiento
¿Qué son las reglas?
Identificación de dependencias
Creación y mantenimiento de reglas con el Editor de conjuntos de reglas
Conclusión
Recursos adicionales

Se aplica a:   Microsoft SharePoint Server 2010 | Microsoft SharePoint Foundation 2010
Autor:   David Mann, Mann Software (MVP de SharePoint)

Contenido

  • Flujos de trabajo de SharePoint y el motor de reglas de Windows Workflow Foundation

  • Objetivo: Separar la lógica de negocios de la lógica de procesamiento

  • ¿Qué son las reglas?

  • Identificación de dependencias

  • Creación y mantenimiento de reglas con el Editor de conjuntos de reglas

  • Conclusión

  • Recursos adicionales

Flujos de trabajo de SharePoint y el motor de reglas de Windows Workflow Foundation

Los flujos de trabajo son aplicaciones que aplican procesos de negocio, que incluyen una serie de actividades y las estructuras de control que los conectan. La aplicación necesita una forma de realizar la transición de una actividad a otra hasta que finalice el proceso. Pero la complejidad se produce porque algunas partes de los procesos suelen estar sujetas a cambios, mientras que la lógica principal del flujo de trabajo permanece fija. Por ejemplo, los umbrales que requieren distintos niveles de aprobación e intervalos de tiempo para la remisión de tareas a un nivel superior son ejemplos de condiciones que pueden variar a medida que cambian las necesidades de la empresa. Pero, por lo general, la lógica en la que se basan estos procesos no sufre cambios: aún se requieren aprobaciones y la remisión de tareas a un nivel superior para su finalización. En estos casos, un motor de reglas de negocio puede proporcionar un marco de trabajo compatible con las "partes móviles" y la lógica de negocios principal. Antes de intentar comprender el motor de reglas y cómo funciona, es importante que comprenda el problema del que se ocupa esta herramienta.

Objetivo: Separar la lógica de negocios de la lógica de procesamiento

Como se indica en el título de esta sección, el objetivo es segmentar un proyecto de flujo de trabajo de forma que se separe la lógica de negocios de la lógica que controla el procesamiento del flujo de trabajo. En otras palabras, el código que crea y actualiza tareas, manipula elementos de lista y documentos y realiza otras tareas no debe entremezclarse con el código o el marcado que expresa la información sobre la empresa. La identificación de los usuarios que deben dar su aprobación para elementos específicos y la cantidad de tiempo que tienen los usuarios para revisar los documentos es información que se debe separar de la lógica de negocios subyacente. En el ejemplo 1 se incluyen dos escenarios que muestran por qué, desde el punto de vista del mantenimiento, es importante separar y controlar la lógica de negocios y la lógica de procesamiento.

Ejemplo 1: Una regla de valor de umbral sencilla para el enrutamiento

Imagine que está escribiendo un flujo de trabajo que redirige un documento para su aprobación. Según los requisitos de su empresa, si un determinado revisor no ha actuado en relación con la tarea de revisión asignada dentro de los cinco días, el documento se debe considerar no aprobado y debe avanzar por el resto del proceso de forma adecuada, como si se hubiera rechazado de forma activa. Pero teniendo en cuenta cómo suelen ser los requisitos empresariales, es muy probable que poco tiempo después de implementar este flujo de trabajo personalizado alguien se dé cuenta de que cinco días no son suficientes para un período de revisión y de que la ausencia de acción por parte de un revisor ha provocado un "veto indirecto", lo que llevará a la conclusión de que los aprobadores necesitan al menos dos semanas para revisar y aprobar una tarea. Lo más probable es que esto ocurra un viernes por la tarde y que deba implementarse antes del lunes por la mañana. Además, deberá implementarse para todas las instancias de flujo de trabajo actualmente en proceso.

¿Qué escenario prefiere?

  • Escenario 1: Comprobar el código fuente fuera del sistema de control de código fuente, leer todo el código para encontrar en qué lugar el período de revisión se codificó de forma rígida (probablemente en varios lugares) y, a continuación, realizar el cambio, someter el proceso a una serie de pruebas, volver a empaquetarlo, volver a implementarlo y esperar que no se produzca ningún error en los nuevos flujos de trabajo que se inician o en cualquiera de las instancias que ya están en proceso.

  • Escenario 2: Realizar un cambio en un solo archivo XML a través de una aplicación cliente personalizada y guardarlo en el servidor.

La respuesta es obvia.

Hay varias formas de controlar una situación como esta: por ejemplo, mediante servicios web, entradas de bases de datos o archivos planos sencillos. Sin embargo, debe tener en cuenta que este es un ejemplo básico y que el uso de un motor de reglas para un valor de umbral simple agrega un nivel de complejidad completamente innecesario. Pero imagine una situación más compleja, como la que se describe en el ejemplo 2.

Ejemplo 2: Reglas de enrutamiento complejas

Supongamos que tiene el mismo proceso de aprobación de documentos que incluye la misma posibilidad de un "veto indirecto" (debido a la falta de respuesta a tiempo por parte de un revisor), pero ahora el proceso de flujo de trabajo contiene los siguientes requisitos adicionales:

  • Si la persona que no cumple con un intervalo de tiempo de revisión es un director o un empleado de nivel superior, el documento no se rechaza automáticamente. En su lugar, se asigna la tarea al asistente administrativo, que ahora tiene un nuevo plazo para aprobar el documento.

  • Los plazos de aprobación se ajustan a partir de un valor de base y se incrementan o disminuyen según la prioridad del documento.

  • Si el autor del documento es un vicepresidente o el asistente administrativo de un vicepresidente, se quita la opción de veto indirecto y, en su lugar, se implementa una serie de intervalos de tiempo de remisión a un nivel superior.

  • Si se determina que el documento tiene un cierto nivel de confidencialidad, independientemente de otros factores, no se muestra nunca a los asistentes administrativos información relacionada con sus tareas que pudiera revelar el contenido del documento. Simplemente se les indica que deben pedir la revisión de un documento al superior que tienen asignado.

En este escenario más complejo, entran en juego varios factores adicionales: varios períodos de revisión de duración variable que tienen valores de umbral únicos, reglas que se imponen sobre otras reglas, reglas que requieren la reevaluación de otras reglas, reglas que producen cambios en otras reglas, etc.

La implementación del segundo ejemplo con cualquiera de las opciones que funcionaban en el primer ejemplo se vuelve mucho más difícil. Es posible que se pueda usar una base de datos personalizada y servicios web, pero sería mucho más difícil de implementar. Para complicar las cosas aún más, el número de opciones que se deben administrar aumentó considerablemente. Además, si se necesita un nuevo flujo de trabajo prácticamente igual que solo tiene una o dos diferencias con respecto a este segundo ejemplo, se deberá reproducir la mayor parte de la misma lógica y mantener dos copias, o bien se deberá crear una aplicación genérica que pueda controlar ambos flujos de trabajo y un tercero, cuarto, quinto, etc.

La situación descrita en el ejemplo 2 muestra la necesidad de usar un "motor de reglas".

¿Qué son las reglas?

En su forma más sencilla, las reglas son componentes lógicos que dan como resultado un valor Boolean que se puede usar para ramificar el proceso de flujo de trabajo siguiendo cualquiera de varias rutas posibles. A este nivel, las reglas no tienen nada especial. Se denominan condiciones y son similares al umbral simple que se describió en el ejemplo 1.

Las reglas se pueden usar como condiciones en varias actividades, tales como:

  • IfElseBranch

  • While

  • ActivityGroup condicionada

  • Replicator

En cada uno de estos casos, la condición es simplemente una evaluación Boolean. La actividad específica que contiene la condición se comporta de forma diferente según el resultado de la evaluación de la condición. En el caso más simple de una actividad IfElseBranch, si la condición es true, la rama ejecuta sus actividades secundarias; si la condición es false, la rama no hace nada. Las demás actividades funcionan de forma similar.

Las condiciones se pueden implementar de dos maneras distintas: como condiciones de código o como condiciones declarativas. Obviamente, el uso de condiciones de código implica escribir código en un ensamblado personalizado que se ejecuta para llegar al valor Boolean de la condición. Las condiciones declarativas usan el Editor de condiciones (ilustrado en la figura 1), que se integra en las extensiones de flujo de trabajo para Microsoft Visual Studio. En el ejemplo 3 se incluyen condiciones declarativas de ejemplo. Aunque es cierto que también se debe escribir código en el Editor de condiciones, normalmente este código solo implementa comparaciones simples, por lo que no presenta la complejidad que supone escribir código personalizado.

Figura 1. Editor de condiciones

Editor de condiciones

Ejemplo 3: Condiciones declarativas

Todos los siguientes son ejemplos de condiciones simples:

this.po_amount > 1000 and reviewer.role < userrole.director

privacy_level == "restricted"

document_owner.division = Divisions.Finance

date_now > required_approval_date

La implementación de una condición en código le da la flexibilidad para hacer todo lo que necesite hacer. Todo lo que se puede hacer en Microsoft .NET Framework se puede hacer en una condición de código, para llegar al resultado Boolean necesario. Puede interactuar con bases de datos, servicios web, objetos personalizados, evaluaciones complejas, etc. En el caso de las condiciones declarativas, las opciones disponibles son algo limitadas en función de su viabilidad. También deberá escribir código y ese código podrá realizar la mayoría de las acciones que puede hacer una condición de código completa. Sin embargo, para comparaciones menos simples, probablemente es conveniente usar una condición de código desde el principio.

Teniendo en cuenta lo que he explicado hasta ahora, es posible que se pregunte si las reglas son realmente útiles. Parecen aumentar la complejidad sin ofrecer ninguna ventaja. Sin embargo, las cosas mejoran. Para ver por qué, debe entender dos cosas: la actividad Policy y RuleSets.

Actividad Policy en Windows Workflow Foundation

La actividad Policy es una herramienta integrada incluida en Windows Workflow Foundation y, por lo tanto, está disponible para flujos de trabajo de SharePoint. Una directiva es un conjunto de reglas relacionadas que funcionan juntas para definir requisitos empresariales. Esto es exactamente lo que hace la actividad Policy: encapsula la definición y la ejecución como un grupo de reglas denominado RuleSet. (Para obtener más información, vea la sección siguiente, RuleSets en Windows Workflow Foundation).

Las condiciones descritas anteriormente actúan como una marca Boolean para determinar si un proceso de flujo de trabajo continúa y cómo lo hace. Son las partes if de una instrucción if-then-else. En los ejemplos anteriores, eso era suficiente; las actividades se encargaban del resto. En otros escenarios, se necesita más y la actividad Policy lo proporciona. La actividad Policy permite anexar la parte then-else al final para completar la funcionalidad. Puede aplicarse cuando es necesario realizar más actividades. El trabajo de la actividad Policy consiste en administrar la creación y ejecución de reglas de un RuleSet.

La actividad Policy en sí es simple. Solo contiene una propiedad importante de la que debería preocuparse: RuleSetReference. (Las demás propiedades son Name, Description y Enabled, todas relativamente autoexplicativas). La propiedad RuleSetReference, como el nombre indica, contiene una referencia al RuleSet que ejecuta esta actividad Policy en el tiempo de ejecución. También proporciona acceso a una interfaz de usuario para administrar ese RuleSet, que es lo que realmente impulsa el motor de reglas.

RuleSets en Windows Workflow Foundation

Un RuleSet es un conjunto de reglas con un conjunto de semántica de ejecución. Consta de lo siguiente:

  • Una o varias condiciones

  • Cero o más acciones que se realizarán si las condiciones se evalúan como true

  • Cero o más acciones que se realizarán si las condiciones se evalúan como false

  • Metadatos que se usan para controlar la ejecución de las reglas, como los siguientes:

    • Nombre

    • Prioridad

    • Marca activa

    • Condiciones de reevaluación

    • Comportamiento de encadenamiento

En las siguientes secciones se examina en más detalle cada una de las reglas y su semántica y, para finalizar, se incluye una revisión de la aplicación Editor de conjuntos de reglas proporcionada por Microsoft.

Acciones de regla

Las acciones que realiza una regla se pueden ejecutar si las condiciones se evalúan como true o false. Se trata de las partes then y else de la regla y pueden contener cualquier lógica necesaria: llamar a servicios web, usar objetos personalizados, establecer valores de campo, etc. Una acción puede ser cualquier cosa para la que se pueda escribir código en .NET Framework, aunque deberá tener en cuenta estas consideraciones importantes:

  • El objeto al que hace referencia esta acción en el flujo de trabajo.

  • Los campos o métodos de objetos personalizados deben ser estáticos, ya que no es posible crear instancias.

  • No se pueden crear instancias de objetos directamente. Sin embargo, es posible escribir un objeto personalizado con un método estático que cree una instancia y funcione con otros objetos.

Aparte de estas pocas consideraciones, puede hacer todo lo que necesite hacer dentro de las acciones. Podrá ver el aspecto de la interfaz correspondiente al examinar el Editor de conjuntos de reglas.

Ejemplo 4: Acciones

En este ejemplo se muestran algunas Actions de ejemplo, en la parte then y else del RuleSet.

this.SomeVariable = SomeValue

myObject.myStaticMethod()

myObject.SomeStaticField=this.workflowProperties.List.Title

Nombre

Un nombre es la identidad que se da a cada regla.

Prioridad

Una prioridad le permite controlar el orden en que se ejecutan las reglas cuando se ejecuta la directiva. Las reglas se ejecutan en orden de prioridad descendente, por lo que una regla de prioridad 5 se evalúa antes que una regla de prioridad 4, una regla de prioridad 2 se evalúa antes que una regla de prioridad 1, y así sucesivamente. De manera predeterminada, todas las reglas se inician con una prioridad de 0. Para hacer que una regla se ejecute en último lugar sin cambiar la prioridad de las demás reglas, puede especificar prioridades negativas.

Marca activa

Una marca activa es un valor Boolean que indica si una determinada regla está activa. Esto le permite mantener las reglas en el RuleSet pero impedir que se ejecuten.

Condiciones de reevaluación

Una condición de reevaluación es un valor relativamente básico en la superficie pero que tiene implicaciones de gran alcance. Hay solo dos opciones: Always y Never. El valor predeterminado es Always. Para comprender bien las consecuencias de esta configuración, debe comprender el concepto de encadenamiento, que se describe más adelante en este artículo. Por ahora, tenga en cuenta lo siguiente:

  • Always significa que cuando el motor de reglas determina que se debe reevaluar una regla específica de un RuleSet, esta se reevaluará.

  • Never significa que aunque el motor de reglas determine que se debe reevaluar una regla específica de un RuleSet, esta no se reevaluará. Es importante señalar que se considera que una regla se evaluó solo si ejecuta su acción then o else no vacía. Además, este valor actúa solo para controlar la reevaluación y no tiene ningún efecto en la evaluación inicial. Para impedir la evaluación inicial, debe usar la marca Active que se explicó anteriormente.

Verá una condición de reevaluación en acción en la descripción de "encadenamiento" en la sección Encadenamiento de flujos de trabajo más adelante en este artículo. Pero primero debe aprender cómo se identifican las dependencias entre reglas, ya que estas dependencias desencadenan la reevaluación.

Identificación de dependencias

Las dependencias entre las reglas se producen cuando una regla realiza un cambio que afecta a la evaluación de otra regla. El caso más básico se muestra en el ejemplo 5.

Ejemplo 5: Dependencia simple

En este ejemplo se muestra una dependencia simple entre reglas.

Regla 1: if x=5 then y=7

Regla 2: if y=3 then z=4

La regla 2 tiene una dependencia de la regla 1, ya que la regla 1, si ejecuta su acción then actualiza la variable y, que se usa en la condición de la regla 2.

Las dependencias pueden ser más complejas, como veremos en breve. Hay tres formas de identificar una dependencia: Implicit, Attribute-Based y Explicit.

Dependencia implícita

Aunque el ejemplo 5 no se identifica como tal, usa un modelo implícito para identificar las dependencias. El motor de reglas pasa por el RuleSet y busca escenarios como este, en el que una regla afecta directamente a la evaluación de la condición de otra regla. Este es el comportamiento predeterminado.

Dependencia de atributos

La dependencia de atributos es útil solo cuando una regla llama a un método personalizado. El uso de objetos personalizados suele crear confusión en las interdependencias y puede hacer que el motor de reglas no logre identificar las dependencias. Para resolver este problema, hay tres atributos con los que los programadores pueden decorar sus métodos para proporcionar la información que necesita el motor de reglas:

  • RuleRead("PropertyName") El método decorado con este atributo lee el valor de propiedad especificado.

  • RuleWrite("PropertyName") El método decorado con este atributo actualiza el valor de propiedad especificado.

  • RuleInvoke("MethodName") El método decorado con este atributo realiza una llamada a otro método, que debe estar decorado con el atributo RuleRead o con el atributo RuleWrite.

En el ejemplo 6 se muestra cada uno de estos atributos.

Ejemplo 6: Dependencias de atributos

Un método que lee un valor de la propiedad está decorado con el atributo RuleRead, como se muestra en el siguiente ejemplo de código.

[RuleRead("ApproverRole")]
public UserRole GetApproverRole(string UserName)
{

    // Do some processing here to determine the role of the user, based   
    // upon the ApproverRole property.
    return Role;
}

Un método que actualiza una propiedad está decorado con el atributo RuleWrite, como se muestra en el siguiente ejemplo de código.

[RuleWrite("ApprovalThreshold")]
public void SetApprovalThreshold(int BaseDays, UserRole Role)
{
    // Do some processing here to calculate the number of days users 
    // have to complete tasks based on their role in the organization
    // and update the ApprovalThreshold property.
}

Un método que no interactúa directamente con una propiedad también puede estar decorado con el atributo RuleInvoke para indicar que llama a otro método que sí interactúa con una propiedad.

[RuleInvoke("SetApprovalThreshold")]
[RuleInvoke("GetApproverRole")]
Public void CalculateAndAssignThresholdBasedOnRole(string UserName)
{
    UserRole Role = GetApproverRole(UserName);
    // Calculate BaseDays here.
    SetApprovalThreshold(BaseDays, Role);
}

Tenga en cuenta que en el ejemplo de código anterior, se usan varios atributos. Tenga en cuenta también que los métodos de destino del atributo RuleInvoke están decorados con el atributo RuleRead o el atributo RuleWrite.

Por último, tenga en cuenta estas consideraciones acerca de cómo identificar dependencias:

  • Puede especificar que todos los campos de un objeto se lean o se escriban mediante el uso de un asterisco (*). Por ejemplo, [RuleRead("ApproverRole/*")] indica que se lean todos los campos del objeto que posee el campo ApproverRole. Se puede usar el mismo enfoque para atributos RuleWrite.

  • Si no se especifica ningún atributo, se supone que una llamada a un método lee todas las propiedades y campos del objeto de destino pero no escribe en ninguno. Se supone que se leen los parámetros que se pasan al método, pero solo se escribe en los parámetros out o ref.

Dependencia explícita

El atributo Explicit es útil cuando se realiza una llamada a un método del que no se tiene el código fuente, o cuyo código fuente no se puede alterar para decorar el método de destino con los atributos apropiados. Esta identificación de dependencia se agrega directamente a la regla en el Editor de conjuntos de reglas mediante una instrucción Update, como se muestra en el ejemplo 7. En algunas situaciones, también se puede usar para cualquier llamada de método en la que se deben identificar las dependencias de forma explícita.

Ejemplo 7: Identificación explícita de dependencias

En este ejemplo se muestra el uso de la instrucción Update() para identificar de forma explícita una dependencia.

If x > 7 then SomeExternalMethodThatUpdatesY()

Update(y)

Encadenamiento de flujos de trabajo

El "encadenamiento" permite encadenar flujos de trabajo entre sí, es decir, llamar a un flujo de trabajo totalmente nuevo desde dentro de una actividad de otro flujo de trabajo. El encadenamiento se basa en las dependencias identificadas entre reglas, específicamente, en las dependencias existentes entre las acciones de una regla y las condiciones de otras reglas. Con el encadenamiento, empiezan a complicarse las cosas. El concepto en sí es bastante simple: existe el potencial de establecer relaciones entre las reglas por las cuales la acción then o else de una regla realiza alguna acción (por ejemplo, establecer una variable) que produce la reevaluación de otra condición de regla dependiente. Lamentablemente, no es tan simple en todos los casos. Estas dependencias se identifican mediante los métodos descritos anteriormente e incluyen dependencias implícitas, explícitas o de atributos.

El encadenamiento permite controlar la forma en que se reevalúan las reglas, en función de lo siguiente:

  • Cambios realizados por otras reglas

  • Dependencias identificadas por el motor de reglas (teniendo en cuenta directivas específicas)

  • Una condición de reevaluación establecida para el RuleSet en general

Estas son las tres opciones para establecer un encadenamiento:

  • Full Todas las dependencias se siguen de forma bidireccional y las reglas se reevalúan según sea necesario.

  • Explicit Update Only Solo se respetan las dependencias que se identifican con una instrucción Update específica.

  • Sequential El encadenamiento está desactivado. Las reglas se ejecutan solo una vez, por orden de prioridad descendente, y no se vuelven a reevaluar.

Full es la opción más complicada. Full produce una malla potencial de reglas interrelacionadas que puede ser muy compleja. La probabilidad de generar una referencia circular en un entorno complejo de encadenamiento completo es muy alta. En el ejemplo 8 se describe un método sencillo y genérico para ayudarle a comprender el concepto. El ejemplo 8 está seguido de un ejemplo real que demuestra la eficacia y complejidad potencial del encadenamiento.

Ejemplo 8: Encadenamiento simple

Los siguientes son ejemplos de encadenamiento simple.

Regla 1 (Prioridad: 3, Reevaluación=Always): If x=2 then x=5

Regla 2 (Prioridad: 2, Reevaluación=Always): If y=3 then z=7 and x=2 else z=4

Regla 3 (Prioridad: 1, Reevaluación=Always): If z=4 then y=3

Hay dos dependencias en este RuleSet. Las dos son bastante obvias:

  • La regla 3 depende de la regla 2 porque la condición de la regla 3 se basa en el valor de z, que se establece en la acción else de la regla 2.

  • La regla 2 depende de la regla 3 porque la condición de la regla 2 se basa en el valor de y, que se establece en la acción then de la regla 3.

Suponga que el encadenamiento del RuleSet está establecido en Full y que empieza con los valores iniciales siguientes:

x=0

y=7

z=2

A continuación, recorriendo las reglas una por una, ocurre lo siguiente:

  1. La regla 1 se ejecuta en primer lugar porque tiene la prioridad más alta. Debido a que su condición se evalúa como false (x != 2), su acción then nunca se ejecuta, por lo que no hay cambios.

  2. La regla 2 (prioridad 2) se ejecuta a continuación. Una vez más, la condición se evalúa como false, por lo que su acción then no se ejecuta. Sin embargo, su acción else sí se ejecuta, por lo que el valor de z cambia a 4.

  3. La regla 3 se ejecuta en último lugar. La condición se evalúa como true (z = 4), por lo que su acción then se ejecuta y cambia y a 3.

  4. Si el encadenamiento se establece en cualquier valor distinto de Full, la ejecución podría detenerse aquí. Sin embargo, debido a que el encadenamiento se establece en Full y la reevaluación en Always, la regla 2 se reevalúa.

  5. En este caso, la condición de la regla 2 se evalúa como true, de modo que z se establece en 7 y x en 2.

  6. Esto desencadena más reevaluaciones: para la regla 1 y para la regla 3. La regla 1 se reevalúa en primer lugar porque tiene una prioridad más alta.

  7. En este caso la condición de la regla 1 se evalúa como true, de modo que x cambia a un valor de 5.

  8. A continuación, se reevalúa la regla 3. La condición se evalúa como false, por lo que no ocurre nada y finaliza el RuleSet.

Se termina con los valores siguientes:

x=5

y=3

z=7

Aunque el ejemplo anterior es relativamente básico, transmite claramente el punto. Lamentablemente, en la vida real no se trabaja con valores enteros simples en las reglas de negocios. Se trabaja con personas, intervalos de tiempo y responsabilidades. Entran en juego la política de la oficina, que siempre complica las cosas. Además, como las personas van y vienen, normalmente deberá tratar con roles en lugar de personas.

En el ejemplo 9 se muestra parte de esa complejidad. Este ejemplo hace algunas suposiciones acerca del uso de variables y otros factores por razones de brevedad, por lo que no debe preocuparse acerca de algunos de estos detalles complementarios. Simplemente concéntrese en la lógica de negocios. Este ejemplo también está escrito en pseudocódigo para simplificar la exposición. En este ejemplo, se usa un RuleSet para determinar la cantidad de días que tiene un revisor para aprobar o rechazar un documento en una fase de un flujo de trabajo.

Ejemplo 9: Encadenamiento real

El siguiente es un ejemplo de encadenamiento real.

Regla 1 (Prioridad: 4, Reevaluación=Never): If 1=1 then BaseReviewCycleDays=5

Regla 2 (Prioridad: 3, Reevaluación=Always): If DocumentPriority=High then ReviewCycleDays=BaseReviewCycleDays - 2 else ReviewCycleDays=BaseReviewCycleDays

Regla 3 (Prioridad: 2, Reevaluación=Never): If Reviewer > RegularReviewer then ReviewCycleDays += 3

Regla 4 (Prioridad: 1, Reevaluación=Always): If DocumentAuthor > Director then DocumentPriority=High

Regla 5 (Prioridad: -1, Reevaluación=Never): If Approver.IsExecutive and ReviewCycleDays < 5 then ReviewCycleDays = 5 and Halt

En esta sección no se describe de forma detallada este ejemplo, pero puede completarlo si está interesado. Basta con decir que si el documento está marcado como de prioridad normal y fue creado por un vicepresidente, y el revisor no es un ejecutivo, el resultado es que el revisor tiene tres días para revisar el documento. Si se cambia el revisor por un ejecutivo y el autor por un "no ejecutivo", el ciclo de revisión se extiende a ocho días.

Un comentario acerca de este ejemplo: tenga en cuenta el uso de la palabra Halt al final de la regla 5. Se trata de una directiva que indica al motor de reglas que deje de procesar el RuleSet y que vuelva inmediatamente al flujo de trabajo con todos los valores tal como están en ese momento. No es una condición de error, sino una forma de interrumpir el procesamiento de reglas en caso de que surja la necesidad. En este caso, se garantiza que no se reevaluará nada después de evaluar la regla 5.

Aunque este ejemplo es más real que el primer ejemplo de encadenamiento y, en algunos aspectos, más complejo, también resulta bastante fácil de seguir. Escribir el código correspondiente de forma manual es bastante sencillo. Sin embargo, recuerde que se trata tan solo de una parte de un paso en un único flujo de trabajo. Esta parte solo determina cuánto tiempo tiene un revisor para actuar en un documento. Si se multiplica esta actividad por cinco o seis revisores y se agrega un conjunto completamente distinto de suposiciones y condiciones, empezará a apreciar el grado de complejidad que pueden alcanzar las actividades de flujo de trabajo y los requisitos.

Ahora, imagínese que debe realizar un cambio en parte de la lógica. Sería perfecto si la lógica de negocios estuviera separada del resto de la lógica de flujo de trabajo y se pudiera mantener en una aplicación independiente que simplificara la tarea mostrando solo lo que necesita ver para mantener las reglas de negocio. Esta es precisamente la ventaja del motor de reglas.

Para finalizar esta descripción del encadenamiento, una última advertencia: procure evitar las referencias circulares. Es una posibilidad muy real. De hecho, es muy probable que en algún momento provoque una referencia circular entre las reglas y que, en consecuencia, el proceso se bloquee. Antes de implementar una solución en producción, pruébela con una amplia gama de valores o combinaciones de valores para los distintos elementos de sus RuleSets.

Creación y mantenimiento de reglas con el Editor de conjuntos de reglas

Ahora que conoce toda la "infraestructura" de una regla, integre lo aprendido revisando la aplicación que ofrece Microsoft para editar un RuleSet: el Editor de conjuntos de reglas, ilustrado en la figura 2.

Figura 2. Editor de conjuntos de reglas para la creación y mantenimiento de reglas y metadatos

Aplicación del editor de conjuntos de reglas

La aplicación Editor de conjuntos de reglas presenta una interfaz que permite crear reglas y mantener metadatos del RuleSet. Lo que debe saber acerca de esta aplicación es que está disponible para su uso en aplicaciones personalizadas de Windows mediante el uso de la clase RuleSetDialog. Debido a que el Editor de conjuntos de reglas se implementa como un cuadro de diálogo estándar de Windows, al igual que los cuadros de diálogo Guardar y Abrir, puede rehospedarlo fácilmente en la aplicación personalizada.

Lamentablemente, el Editor de conjuntos de reglas solo está disponible para aplicaciones Windows; no está disponible para aplicaciones web.

Esto plantea un problema importante. Después de todo, SharePoint es una aplicación web y está intentando usar el motor de reglas desde la aplicación web. Lamentablemente, esto significa que no podrá alcanzar su objetivo desde aquí. Sin embargo, puede aprovechar lo que tiene y, con un poco de trabajo adicional, llegar a su objetivo. Esto es lo que ha logrado hasta ahora:

  • Ha separado la lógica de negocios de la lógica de procesamiento de flujo de trabajo

  • Ha aprendido cómo aprovechar el motor de reglas como una herramienta para administrar la lógica de negocios

Quizá no haya logrado la simplicidad que insinuamos al final del escenario 2 del ejemplo 1: mantener las reglas no es tan sencillo como editar un archivo XML y guardarlo en el servidor.

Sin embargo, con un poco más de trabajo, podría resultar más sencillo. Aunque en este artículo no hay lugar para una explicación detallada de cómo crear la solución completa, en la sección final de este artículo se describen los pasos necesarios para hacerlo correctamente.

Archivo .rules

Es importante entender cómo se almacenan los RuleSets para que puedan estar disponibles para la actividad Policy. Si presta atención a la ventana Explorador de soluciones en Visual Studio mientras agrega reglas a un RuleSet, podrá ver que se agrega un archivo .rules. Este es el archivo que mantiene la información acerca de las reglas y es el archivo XML que se mencionó en el escenario 2 del ejemplo 1. Este es el archivo que debe cambiar cuando cambian las reglas. El archivo .rules es una representación serializada de su RuleSet. No se incluye ningún ejemplo de un archivo .rules aquí ya que no hay archivos .rules "cortos". Incluso la regla más simple, if 1==1 then this.someVariable = 5, tiene aproximadamente 50 líneas de XML.

Afortunadamente, la aplicación Editor de conjuntos de reglas que se describió anteriormente facilita la creación y edición de un archivo .rules simple. Como se mencionó anteriormente, el Editor de conjuntos de reglas se implementa como un cuadro de diálogo estándar. Al hacer clic en Aceptar, el RuleSet que creó estará disponible en la propiedad RuleSet de la clase RuleSetDialog. Convertirla a un archivo es una simple cuestión de serialización. El único truco es usar la clase WorkflowMarkupSerializer en lugar de las clases de serialización XML estándar.

De manera predeterminada, cuando se compila un flujo de trabajo, el archivo .rules se almacena como un recurso, tal como se muestra en la figura 3. Cuando se ejecuta la actividad Policy, busca el RuleSet como un recurso en el ensamblado principal. Obviamente, esto no sirve para lo que desea realizar en este caso, ya que la modificación del archivo .rules implicaría volver a compilar e implementar el ensamblado. Para simplificar las cosas, necesita una actividad Policy personalizada que busque archivos .rules en otra parte.

Figura 3. Los archivos .rules se insertan en un ensamblado de flujo de trabajo como recursos

Archivos de reglas incrustados en el ensamblado de flujo de trabajo

Actividad ExternalPolicy

La última parte de la solución es una actividad de flujo de trabajo personalizada que busca en otro lugar que no sea el ensamblado que la contiene la definición de su RuleSet. Esta ubicación puede ser una base de datos de Microsoft SQL Server, un archivo del sistema de archivos del servidor o una biblioteca de documentos de SharePoint. Cualquier ubicación que le permita recuperar el archivo de reglas serializado y usarlo para volver a crear y ejecutar un RuleSet. En el ejemplo 10 se muestra en rasgos generales cómo se vería el método Execute de una actividad de este tipo. En este caso, el archivo .rules se recupera de una dirección URL específica, como, por ejemplo, la dirección URL de una biblioteca de documentos de SharePoint.

Ejemplo 10: Ejecución de una directiva almacenada externamente

En el ejemplo siguiente se muestra el principio de una aplicación de reglas administrada de forma externa.

WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
XmlReader reader = XmlReader.Create(UrlOfRuleFile);

// Deserialize the .rules file into a RuleSet object.
RuleSet ruleSet = (RuleSet)serializer.Deserialize(reader);
reader.Close(); 

// Next, use a custom method that returns the root of the workflow as  
// an activity.
Activity target = GetRootOfWorkflowAsActivity(); 
RuleValidation validation = new 
     RuleValidation(target.GetType(), null);
RuleExecution execution = new RuleExecution(validation,target, ctx);
ruleSet.Execute(execution);

Una de las ventajas de almacenar el archivo .rules en una biblioteca de documentos de SharePoint es que se puede aprovechar el control de versiones, las alertas, la papelera de reciclaje, la aprobación y otras capacidades avanzadas que incluye SharePoint. Incluso puede tener un flujo de trabajo en ejecución para procesar los cambios realizados en un archivo .rules para otro flujo de trabajo.

Comprobación de viabilidad: ¿No se puede usar código?

En cualquier situación en la que se pueda usar el motor de reglas, también se puede usar código. Sin embargo, esto no es viable para los escenarios incluso moderadamente complejos, especialmente los muy volátiles. En estos casos, el motor de reglas permite administrar las reglas complejas y cambiantes sin necesidad de escribir y volver a escribir código. El uso del motor de reglas no está dirigido a escenarios sencillos. Para evaluaciones Boolean simples, basta el código o las condiciones declarativas. Para escenarios más complejos, la escritura del código equivalente requeriría un gran esfuerzo.

Conclusión

En este artículo se describen las capacidades y ventajas del motor de reglas de Windows Workflow Foundation que está disponible para los flujos de trabajo en SharePoint 2010. El motor de reglas de Windows Workflow Foundation no está pensado para su uso con todos los flujos de trabajo de SharePoint. Es muy útil para escenarios complejos y avanzados. Se destaca especialmente en la administración y evaluación de lógica de negocios compleja e interrelacionada. En estos casos, podrá contar con el motor de reglas de Windows Workflow Foundation para simplificar su tarea.

Recursos adicionales

Para obtener más información, vea los siguientes recursos: