Partilhar via


Introdução ao mecanismo das regras do Windows Workflow Foundation

 

Jurgen Willis
Microsoft Corporation

Fevereiro de 2006

Aplica-se a:
   Windows Workflow Foundation (WF) Beta 2
   Visual Studio 2005

Resumo: Este artigo fornece uma visão geral dos recursos do mecanismo de regras no WF (Windows Workflow Foundation). Ele descreve como condições e RuleSets são usados no WF e discute o comportamento de coleções de regras, incluindo encadeamento e rastreamento e rastreamento. (18 páginas impressas)

Nota Este artigo foi escrito usando o beta 2 e, no futuro, algumas alterações podem precisar ser feitas para que isso funcione em versões posteriores do Windows Workflow Foundation.

Sumário

Introdução
Visão geral das regras no Windows Workflow Foundation
Avaliação de regras
Encadeamento de encaminhamento
Controle de encadeamento de encaminhamento
Discussão de modelagem adicional
Rastreamento e rastreamento
Conclusão
Para obter mais informações

Introdução

Com a disponibilidade do Windows Workflow Foundation (WF), a Microsoft está introduzindo novos recursos de regras à plataforma de desenvolvedor do WinFX. Esses recursos se estendem de condições simples que conduzem o comportamento de execução da atividade até RuleSets complexos executados por um mecanismo de regras de encadeamento de encaminhamento completo.

A funcionalidade de regras permite a modelagem declarativa de unidades da lógica do aplicativo dentro do escopo de um processo comercial geral. Os cenários de exemplo para a tecnologia do mecanismo de regras são validação de pedidos, cálculo de preços, imposição de promoção, gerenciamento de processos de exceção e julgamento e gerenciamento de declarações.

Um dos principais objetivos no desenvolvimento dessa tecnologia era fornecer uma experiência de fluxo de trabalho e regras verdadeiramente integrada. Em todo o setor, as regras e o fluxo de trabalho normalmente têm sido tecnologias bastante distintas, geralmente fornecidas por diferentes fornecedores. Os mecanismos de regras de terceiros geralmente são inseridos ou integrados por provedores bpm (gerenciamento de processos empresariais) e fluxo de trabalho, mas a experiência de desenvolvedor e administração claramente não é perfeita.

Com o WF, a Microsoft tem se concentrado muito em fornecer uma experiência de desenvolvedor perfeita entre o fluxo de trabalho e a modelagem de regras, de modo a permitir que os desenvolvedores incorporem regras facilmente a qualquer momento em seu fluxo de trabalho. Os desenvolvedores podem determinar se devem modelar sua lógica no modelo de fluxo de trabalho, regras ou código sem precisar se preocupar com as implicações de integração dessas decisões. No entanto, isso foi alcançado sem sacrificar a capacidade de executar regras fora do escopo de um fluxo de trabalho.

Um segundo objetivo principal foi fornecer um modelo simples para os desenvolvedores usarem na definição de regras. A tecnologia de regras tem sido, até então, uma tecnologia de nicho, usada por um grupo altamente especializado de profissionais de regras. Embora as melhorias nas ferramentas tenham ampliado o conjunto de indivíduos que usam regras, os modelos geralmente exigem que os usuários sejam muito bem versados na mecânica de implementação do mecanismo subjacente. Ao fornecer recursos de regras para a plataforma, optamos por um modelo que será acessível pela ampla comunidade de desenvolvedores do .NET e, por fim, por não desenvolvedores. Embora sempre haja um certo nível de experiência em domínio, como em qualquer tecnologia, nossa meta é que todos os desenvolvedores do .NET possam aumentar rapidamente o modelo de regras e incorporá-lo facilmente em seus aplicativos.

Além de fornecer um modelo acessível, o WF também fornece um poderoso mecanismo de avaliação para dar suporte a cenários complexos de regras, exigindo avaliação de encadeamento de encaminhamento e controle preciso de avaliação. Isso é fornecido de uma maneira que fornece vários pontos de extensibilidade, permitindo que os desenvolvedores se baseiem em nossa plataforma e forneçam recursos de regras em suporte a um amplo espectro de cenários.

Este documento fornece uma introdução técnica aos recursos de regras entregues no WF e uma visão geral dos recursos disponíveis e seu uso. No final deste documento há uma lista de recursos adicionais que podem ser usados para saber mais sobre a funcionalidade de regras no WF.

Visão geral das regras no Windows Workflow Foundation

A tecnologia de regras é exposta de duas maneiras principais no WF, como condições em atividades e como um RuleSet de encadeamento de encaminhamento na atividade De política. O encadeamento de encaminhamento será discutido posteriormente no documento; resumidamente, refere-se à capacidade de as ações de uma regra fazer com que outras regras dependentes sejam reavaliadas.

Condições de atividade

As condições são usadas pelas quatro atividades a seguir que são enviadas com o WF:

  • IfElseBranch
  • While
  • Replicador
  • ConditionedActivityGroup (CAG)

As condições são usadas para conduzir o comportamento de execução dessas atividades, por exemplo, determinar se um determinado IfElseBranch será executado. As condições podem ser especificadas como CodeConditions, que terá um manipulador configurado no código ao lado ou como ruleConditionReference. Uma RuleConditionReference apontará para uma definição RuleCondition em um arquivo .rules associado ao fluxo de trabalho no projeto de fluxo de trabalho. A experiência no Visual Studio é vista na Figura 1.

Aa480193.intwf_fndrlseng01(en-us,MSDN.10).gif

Figura 1. Criação de condição de regra do WF

Adicionando uma condição de regra

Estas são as etapas envolvidas na adição de uma condição de regra a uma atividade IfElseBranch que está dentro da atividade IfElse:

  1. Quando uma atividade com uma condição é selecionada (como com a atividade IfElseBranch mostrada), uma propriedade Condition é mostrada na grade Propriedades.
  2. Uma lista suspensa para a propriedade Condition permite que o usuário escolha um CodeCondition ou um RuleConditionReference.
  3. Se RuleConditionReference estiver selecionado, a propriedade Condition poderá ser expandida para ver as propriedades ConditionName e Expression .
  4. Depois de fornecer um nome de condição, as reticências na propriedade Expression são selecionadas para iniciar o Editor de Condição de Regra. Esse editor permite que o desenvolvedor digite a condição no formato de texto, com suporte semelhante ao intellisense. O texto é analisado na representação do modelo de objeto associado da RuleCondition.
  5. Depois de selecionar OK, a definição RuleCondition é serializada em um <arquivo WorkflowName.rules> que é adicionado ao projeto.

Para referenciar campos ou propriedades no fluxo de trabalho, você pode digitar isso no editor. Depois que o ponto é digitado, um menu semelhante ao intellisense é exibido que permite que você escolha os membros no fluxo de trabalho (você também pode apenas digitar o membro diretamente). Chamadas aninhadas também podem ser feitas; por exemplo, this.order.Total. Métodos estáticos podem ser chamados em tipos referenciados digitando o nome da classe seguido pelo nome do método, como você faria no código.

Há suporte para expressões com os seguintes operadores relacionais:

  • Igual ("==" ou "=")
  • Maior que (">")
  • Maior ou igual a (">=")
  • Menor que ("<")
  • Menor ou igual a ("<=")

Além disso, você pode usar os seguintes operadores aritméticos:

  • Adicionar ("+")
  • Subtrair ("-")
  • Multiplicar ("*")
  • Dividir ("/")
  • Módulo ("MOD")

As expressões podem ser combinadas/negadas usando os seguintes operadores:

  • AND ("AND", "&&")
  • OR ("OR", "||")
  • NOT ("NOT", "!")
  • Bit a bit e ("&")
  • Bit a bit ou ("|")

O principal motivo para um desenvolvedor usar uma Condição de Regra em vez de uma Condição de Código é que as Condições de Regra se tornam parte do modelo e podem ser atualizadas dinamicamente em runtime na execução de instâncias de fluxo de trabalho. Uma vantagem secundária das Condições de Regra é que, como parte do modelo, ferramentas mais sofisticadas podem ser criadas sobre o modelo para fornecer experiências de criação adicionais, gerenciamento de dependências, análise entre condições e assim por diante.

Atividade de Política

A atividade Policy encapsula a definição e a execução de um RuleSet. Um RuleSet é uma coleção de regras com um conjunto de semântica de execução. As regras são, por sua vez, expressões If-Then-Else que operam nos membros do fluxo de trabalho. A experiência é mostrada na Figura 2 e é análoga à vista com condições de regra.

Aa480193.intwf_fndrlseng02(en-us,MSDN.10).gif

Figura 2. Criação de RuleSet do WF

Adicionando uma atividade de política

Para configurar um conjunto de regras para a atividade de política, siga estas etapas:

  1. Arraste a atividade de política da caixa de ferramentas para o designer de fluxo de trabalho.
  2. No RuleSetReference , um nome é fornecido para o RuleSet.
  3. Selecionar as reticências no campo Definição de Conjunto de Regras inicia o Editor de Conjunto de Regras.
  4. O editor mostra uma coleção de regras em uma caixa de listagem.
  5. Selecionar uma determinada regra mostra suas ações Condition, Then, Else e um conjunto de propriedades adicionais.
  6. Assim como no Editor de Condição de Regra, as ações Condition, Then e Else são inseridas como texto e analisadas na representação do modelo de objeto associada; as regras são criadas com base nos membros no fluxo de trabalho.
  7. A seleção de OK serializa o RuleSet para o arquivo .rules associado ao fluxo de trabalho.

Observe que a seleção das reticências na propriedade RuleSetReference iniciará o editor que permite que o usuário selecione um RuleSet existente ou adicione/renomeie/remova RuleSets, conforme demonstrado na Figura 3.

Aa480193.intwf_fndrlseng03(en-us,MSDN.10).gif

Figura 3. Navegador WF RuleSet

Avaliação de regras

Cada regra em um RuleSet tem um valor de prioridade com um padrão de 0. As regras em um RuleSet podem ser consideradas uma coleção classificada, ordenada pelos valores de prioridade. O avaliador de Regras do WF avalia as regras individualmente e executa as ações da regra com base nos resultados da avaliação da condição da regra.

O mecanismo de avaliação pode ser descrito conceitualmente com o seguinte procedimento:

  1. Comece com a lista de regras ativas.
  2. Localize a regra de prioridade mais alta.
  3. Avalie a regra e execute suas ações Then/Else conforme apropriado.
  4. Se as ações de uma regra atualizarem um campo/propriedade que é usado por uma regra anterior na lista (uma com prioridade mais alta), reavalie essa regra anterior e execute suas ações conforme apropriado. Observe que somente essas regras com uma dependência específica são reavaliadas.
  5. Continue o processo até que todas as regras no RuleSet sejam avaliadas.

Vejamos um exemplo simples. Suponha que você tenha o Seguinte RuleSet, em que A, B e assim por diante, representam dados no fluxo de trabalho.

Regra4 (Prioridade = 4)

IF A = 15
THEN B = 5

Regra3 (P=3)

IF C = 5
THEN B = 10

Regra2 (P=2)

IF D = 2
THEN A = 15

Rule1 (P=1)

IF B = 5
THEN E = 7

Suponha que você tenha os seguintes dados de entrada:

  • A = 0
  • B = 0
  • C = 5
  • D = 2
  • E = 0

A avaliação prosseguiria da seguinte maneira:

  • Rule4 é avaliado; ele é avaliado como falso e, como não tem nenhuma ação Else , nenhuma ação é executada.
  • Rule3 é avaliada como true e sua ação é executada, definindo B = 10. Rule4 não depende do valor de B, portanto, a avaliação prossegue para Rule2.
  • Rule2 é avaliada como true e sua ação é executada, definindo A = 15.
  • Como Rule4 usa o valor de A em suas condições, ela é reavaliada. Ele é avaliado como true e sua ação é executada, definindo B = 5; Rule3 e Rule2 não são reavaliados, pois suas condições não dependem do valor de A. Nenhuma regra anterior depende do valor de B, portanto, a avaliação prossegue para Rule1.
  • Rule1 é avaliada como true e sua ação é executada, definindo E = 7.

O conjunto de dados resultante agora seria:

  • A = 15
  • B = 5
  • C = 5
  • D = 2
  • E = 7

Encadeamento de encaminhamento

Como visto anteriormente, o encadeamento é baseado nas dependências identificadas entre as regras; mais especificamente, as dependências entre as ações de uma regra e as condições de outras regras. Essas dependências podem ser identificadas ou declaradas de uma das três maneiras:

  • Implícita
  • Baseado em atributo
  • Explícita

Implícita

As dependências implícitas são identificadas automaticamente pelo mecanismo. Quando um RuleSet é executado pela primeira vez, cada regra é analisada para avaliar os campos/propriedades que lê em sua condição e grava em suas ações. Isso é feito percorrendo a expressão na condição e nas instruções nas ações. Por exemplo, suponha as regras a seguir.

Regra 1

IF this.subtotal > 10000
THEN this.discount = .05

Regra 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

O mecanismo avaliaria as regras e identificaria que a Regra 1 lê o campo subtotal e grava no campo de desconto. A regra 2 lê os campos de desconto e subtotal e grava no campo total. Portanto, a Regra 2 tem uma dependência da Regra 1; o resultado é que o mecanismo garantirá que a Regra 2 seja avaliada/reavaliada sempre que a Regra 1 executar sua ação Then .

Observe que as dependências são identificadas no nível do nó folha. Siga o seguinte RuleSet.

Regra 1

IF this.order.Subtotal > 10000
THEN this.order.Discount= .05

Regra 2

IF this.order.Discount > 0
THEN this.order.Total = (1-this.order.Discount) * this.order.Subtotal

Regra 3

IF this.order.CustomerType = "Residential"
THEN ...

Uma dependência ainda seria identificada entre as Regras 1 e 2. No entanto, a Regra 3 não teria uma dependência da Regra 1 ou 2, pois nenhuma das atualizações da propriedade CustomerType . Em outras palavras, a dependência é identificada no nível da propriedade CustomerType , não no objeto Order em si.

Por meio do encadeamento implícito, o WF faz a maior parte do encadeamento necessário para o usuário, para que o usuário não precise modelar explicitamente as atualizações e possa, de fato, não estar ciente do encadeamento ou da necessidade dele, na maioria dos casos. Esperamos que isso torne a modelagem de RuleSets complexos mais simples para a maioria dos usuários e torne a noção de encadear uma funcionalidade poderosa, mas principalmente oculta, do mecanismo. No entanto, os dois outros mecanismos para conduzir o encadeamento, baseado em atributo e explícito, são fornecidos para cenários mais complexos e específicos.

Attribute-Based

Para chamadas de método dentro de uma regra, torna-se mais difícil avaliar deterministicamente as leituras/gravações que ocorrem. Para resolver esse problema, o WF fornece três atributos que podem ser aplicados a um método para indicar suas ações:

  • RuleRead
  • RuleWrite
  • RuleInvoke

Atribuir um método com o atributo RuleRead indica que ele lê a propriedade indicada. Da mesma forma, o atributo RuleWrite pode ser usado para indicar que um método atualiza um determinado campo ou propriedade. Suponha que nossas duas primeiras regras na seção implícita foram reescritas como as seguintes.

Regra 1

IF this.subtotal > 10000
THEN this.SetDiscount(.05)

Regra 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

O método SetDiscount poderia então ser atribuído da seguinte maneira, o que permitiria que o mecanismo identificasse que a Regra 2 depende da Regra 1 devido ao uso do campo de desconto.

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
     ...//some code that updates the discount field
}

O atributo RuleInvoke pode ser usado para ditar dependências devido a chamadas de método vinculado. Por exemplo, suponha a modificação a seguir nas regras e métodos.

Regra 1

IF this.subtotal > 10000
THEN this.SetDiscountWrapper(.05)

Regra 2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

[RuleInvoke("SetDiscount")]
void SetDiscountWrapper(double requestedDiscount)
{
     ...
     SetDiscount(requestedDiscount);
     ...
}

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
}

A condição da Regra 2 chama SetDiscountWrapper, que por sua vez chama SetDiscount, que grava no campo de desconto. O atributo RuleInvoke permite que essa gravação indireta seja declarada e detectada pelo mecanismo.

É importante reconhecer que o campo ou a propriedade referenciada no caminho do atributo refere-se a um campo ou propriedade na mesma classe que o método , que não é necessariamente o objeto raiz passado para o RuleSet para execução. Por exemplo, você pode atribuir a classe Order da seguinte maneira.

public class Order
{
     private double discount;

     public double Discount
     {
     get { return discount;}
     set { discount = value;}
     }

     [RuleWrite("Discount")] 
     void CalculateDiscount(double requestedDiscount, double weighting)
     {
...//some code that updates the discount field
     }
}

Em seguida, você pode usar uma instância dessa classe em um fluxo de trabalho da seguinte maneira.

public class Workflow1 :  SequentialWorkflowActivity
{
     private Order discount;

     ...
}

A execução da Regra 2, então, causaria reavaliação da Regra 1.

Regra 1

IF this.order.Discount > 5
THEN ...

Regra 2

IF ...
THEN this.order.CalculateDiscount( 5.0, .7)

Alguns pontos adicionais sobre o uso de atributos:

  • Os atributos apontam para os campos/propriedades na classe Owner , não os parâmetros para uma chamada de método.
  • Curingas também podem ser usados nos atributos de regra. Por exemplo, RuleWrite("order/*") pode ser usado para indicar que todos os campos no objeto referenciados pelo campo "order" são modificados pelo método (neste exemplo, o método estaria no fluxo de trabalho em si, não na classe Order ). No entanto, o curinga só pode ser usado no final do caminho; um atributo como RuleWrite("*/Discount") é inválido.
  • Um atributo como RuleWrite("order") pode ser usado com tipos de referência para indicar que a referência foi alterada, por exemplo, para indicar que a variável agora aponta para uma instância order diferente. Todas as regras que usam um campo/propriedade na variável serão consideradas afetadas, além de todas as regras que testam a própria referência de instância, por exemplo, IF this.order == this.order2.
  • O comportamento padrão se nenhum atributo de método for especificado é que uma chamada de método será considerada para ler todos os campos/propriedades no objeto de destino (o objeto no qual o método é invocado), mas gravar em nenhum deles. Além disso, supõe-se que um método leia os parâmetros que são passados para ele, mas supõe-se que não escreva para nenhum deles. Supõe-se que os parâmetros out e ref sejam gravados quando usados em ações de regra.

Explícita

O mecanismo final para indicar dependências de campo/propriedade é por meio do uso da instrução Update . A instrução Update usa como argumento uma cadeia de caracteres que representa o caminho para um campo ou propriedade ou uma expressão que representa um acesso de campo/propriedade. Por exemplo, qualquer uma das duas instruções a seguir pode ser digitada no editor RuleSet para criar uma instrução Update na propriedade Name de uma instância do Cliente no fluxo de trabalho.

Update("this/customer/Name") 

OU

Update(this.customer.Name)

A instrução Update indica que a regra grava no campo/propriedade indicado. Isso teria o mesmo efeito que um conjunto direto do campo/propriedade na regra ou a chamada de um método com um atributo RuleWrite para o campo/propriedade.

O comando Update também dá suporte ao uso de curingas. Por exemplo, você pode adicionar o comando Update a seguir a uma regra.

Update("this/customer/*")

Isso faria com que todas as regras que usam qualquer propriedade na instância do Cliente em suas condições fossem reavaliadas. Em outras palavras, cada uma das duas regras a seguir seria reavaliada.

IF this.customer.ZipCode == 98052
THEN ...

IF this.customer.CreditScore < 600
THEN ...

Em geral, não se espera que os usuários precisem modelar instruções de atualização explícitas na maioria dos cenários. O encadeamento implícito deve fornecer a análise de dependência necessária e o comportamento de encadeamento na maioria dos cenários. A atribuição de método deve dar suporte aos cenários mais predominantes em que o encadeamento implícito não pode identificar as dependências. Em geral, a atribuição de método seria o método preferencial para indicar dependências sobre o uso da instrução Update , pois a dependência pode ser identificada uma vez no método e aproveitada em várias regras diferentes que usam esse método. Além disso, em cenários em que o gravador de regras e o implementador de método são indivíduos diferentes (ou o trabalho é feito em momentos diferentes), a atribuição de método permite que o gravador de método , que conhece melhor o código, identifique quais são as dependências do método.

No entanto, haverá alguns cenários em que a instrução Update será a solução apropriada, como quando um campo/propriedade é passado para um método em uma classe que o gravador de fluxo de trabalho não controla e, portanto, não pode atribuir, como é o caso no código a seguir.

IF ...
THEN this.customer.UpdateCreditScore(this.currentCreditScore)
     Update(this.currentCreditScore)

Controle de encadeamento de encaminhamento

O encadeamento de encaminhamento é uma noção muito poderosa que permite que as regras atômicas sejam montadas em RuleSets sem a definição ou, necessariamente, até mesmo o conhecimento das dependências entre as regras.

No entanto, em alguns cenários, o gravador de regras pode querer a capacidade de fornecer mais controle sobre o comportamento de encadeamento, especificamente a capacidade de limitar o encadeamento que ocorre. Isso permite que o modelador de regras:

  • Limite a execução repetitiva de regras, o que pode fornecer resultados incorretos.
  • Aumentar o desempenho.
  • Impedir loops descontrolados.

Esse nível de controle é facilitado nas regras do WF por estas duas propriedades:

  • Uma propriedade De comportamento de encadeamento no RuleSet.
  • Uma propriedade Comportamento de Reavaliação em cada regra.

Ambos os valores podem ser definidos no Editor RuleSet.

Propriedade De comportamento de encadeamento

A propriedade Comportamento de Encadeamento no RuleSet tem três valores possíveis:

  • Encadeamento completo
  • Encadeamento explícito
  • Sequencial

A opção Encadeamento Completo é o padrão e fornece o comportamento descrito até este ponto. A opção Encadeamento Explícito desativa o encadeamento implícito e baseado em atributo e prescreve que o encadeamento só deve ocorrer para instruções update explícitas. Isso dá ao gravador de regras controle total sobre quais regras causam reavaliação. Normalmente, isso seria usado para evitar dependências cíclicas que causam re-execução excessiva (ou até mesmo descontrolada) da regra ou para aumentar o desempenho eliminando a reavaliação supérflua da regra não necessária para fornecer integridade funcional do RuleSet.

A opção final é Sequencial. Essa opção fará com que o mecanismo avalie as regras de maneira estritamente linear. Cada regra seria avaliada uma vez e apenas uma vez e na ordem de prioridade. Regras com prioridade mais alta poderiam afetar regras com prioridades mais baixas, mas o inverso não seria verdadeiro, pois nenhum encadeamento ocorreria. Portanto, essa opção seria usada com atribuições de prioridade explícitas, a menos que não existissem dependências entre as regras.

Propriedade De comportamento de reavaliação

O Comportamento de Reavaliação na regra tem dois valores possíveis:

  • Always
  • Never

Sempre é o padrão e fornece o comportamento discutido anteriormente, ou seja, que a regra sempre será reavaliada com base no encadeamento devido às ações de outras regras. Nunca, como o nome indica, desativa essa reavaliação. A regra será avaliada uma vez, mas não será reavaliada se tiver executado alguma ação anteriormente. Em outras palavras, se a regra tiver sido avaliada anteriormente e, consequentemente, tiver executado suas ações Then ou Else , ela não será reavaliada. No entanto, a execução de uma coleção de ações vazia nas ações Then ou Else não marcará uma regra como tendo sido executada.

Normalmente, essa propriedade seria usada, no nível da regra, para evitar loops infinitos devido a dependências que a regra tem, seja em suas próprias ações ou em outras regras. Por exemplo, a regra a seguir criaria seu próprio loop infinito e a reavaliação não é necessária para atender aos requisitos funcionais da regra.

IF this.shippingCharge < 2.5 AND this.orderValue > 100
THEN this.shippingCharge = 0

Como alternativa, se a regra se destina a ser reavaliada — mas somente se o campo OrderValue for alterado — o usuário poderá definir o comportamento de encadeamento no RuleSet para encadear apenas as instruções Update explícitas (e, em seguida, adicionar essas instruções Update às ações de regra relevantes). É claro que o usuário poderia ter adicionado um predicado adicional a essa regra que verifica se o valor de ShippingCost ainda não é 0, mas os controles de encadeamento eliminam a necessidade de os usuários definirem suas regras com base nos detalhes de avaliação, em vez de seus requisitos de negócios.

Função Halt

Como um controle final, uma função Halt pode ser adicionada como uma ação de regra (basta digitar "Parar" nas caixas de ação Then ou Else no editor). Isso interromperá imediatamente a execução de RuleSet e retornará o controle ao código de chamada. A utilidade dessa função não está necessariamente limitada a cenários de controle de encadeamento, é claro. Um RuleSet com uma meta funcional específica, por exemplo, pode usar uma função Halt para execução de curto-circuito depois que a meta for atingida.

Discussão de modelagem adicional

Execução baseada em prioridade

Conforme mencionado em uma seção anterior, se os usuários desejarem uma determinada sequência de execução para o RuleSet ou um subconjunto de regras nesse RuleSet, eles poderão definir precisamente essa sequência usando o campo de prioridade em uma regra. Isso geralmente remove o requisito de encadeamento, e os usuários podem até mesmo desativar o encadeamento nesses cenários. Descobrimos que, em muitos casos, as dependências de regra podem ser atendidas simplesmente fornecendo sequenciamento de execução explícito.

No entanto, é importante observar que o mecanismo de execução de encaminhamento no WF fornece uma capacidade para os usuários definirem uma sequência de execução, mas não exigem que eles o façam. Na maioria dos casos, o comportamento de encadeamento de encaminhamento torna desnecessária a atribuição de prioridades de regra para obter o resultado ruleSet correto, uma vez que as relações são gerenciadas automaticamente pelo mecanismo para garantir que as dependências de regra sejam atendidas.

Siga as regras a seguir.

Regra 1

IF this.Weather.Temperature < 50
THEN this.Drink.Style = "Latte"

Regra 2

IF this.Drink.Style == "Latte"
THEN this.Snack.Style = "Scone"
ELSE this.Snack.Style = "Muffin"

No WF, você pode fornecer uma prioridade mais alta na Regra 1 para que ela seja executada primeiro. Isso garante que Drink.Style seja definido antes da regra 2 ser avaliada.

No entanto, o sequenciamento não é necessário para obter os resultados desejados. Suponha que a Regra 2 foi avaliada primeiro. Nesse caso, o Drink.Style pode ser nulo ou pode ser outro estilo. Isso resultaria na definição do Snack.Style como Muffin. No entanto, depois que a Regra 1 for executada e definir Drink.Style como Latte, a Regra 2 será reavaliada e definirá Snack.Style como Scone. Essencialmente, o usuário tem a opção de ditar o sequenciamento, mas em muitos casos não precisa fazer isso.

Processamento de coleção

Em alguns cenários, talvez seja necessário avaliar as regras em relação a todos os itens individualmente em uma coleção. A iteração pela coleção pode ser feita de várias maneiras, mas uma maneira é com um padrão de regra como este:

Regra 1 (Prioridade = 2)

//always execute this rule once to create the enumerator
IF 1==1 
THEN this.enumerator = this.myCollection.GetEnumerator()

Regra 2 (Prioridade = 1)

IF this.enumerator.MoveNext()
THEN this.currentInstance = this.enumerator.Current

Regras 3-N (Prioridade = 0)

.... //additional rules written against this.currentInstance

Regra N+1 (Prioridade = -1)

// can be any condition as long as it is evaluated every time;
// this.currentInstance will be evaluated each time 
//this.currentInstance changes, whereas 
// "1==1" would only be evaluated once
IF this.currentInstance == this.currentInstance  
                                                                           
THEN ...
         Update("this/enumerator") //this will cause Rule 2 to be reevaluated
ELSE ...
          Update("this/enumerator")

Acompanhamento e rastreamento

Acompanhamento

Quando um RuleSet é executado, os eventos de rastreamento são enviados para os serviços de rastreamento configurados nos hosts que se registraram para esses eventos adicionando um UserTrackPoint ao seu perfil de acompanhamento. Um RuleActionTrackingEvent é enviado, que fornece o nome da regra que foi avaliada, bem como o resultado da avaliação da condição (true/false). Consulte o exemplo RuleActionTrackingEvent no SDK para obter um exemplo.

Os resultados da avaliação das condições de regra nas atividades podem ser rastreados implicitamente por meio do acompanhamento da execução da atividade.

Rastreamento

Informações adicionais de avaliação ruleSet podem ser enviadas a um arquivo de log adicionando o seguinte a um arquivo de configuração de aplicativo.

<configuration>
   <system.diagnostics>
      <switches>
           <add name="Rules" value="Information"/>
      </switches>
   </system.diagnostics>
</configuration>

As seguintes informações serão enviadas para o arquivo de log:

  • Informações de dependência de condição:
    • Exemplo: Dependência da condição "ReturnNumberOfStops" da regra: "this/currentFlight/OutboundFlight/NumberOfStops/"
  • Informações de efeito colateral da ação:
    • Exemplo: Regra "ReturnNumberOfStops" THEN efeito colateral: "this/currentFlight/Score/"
  • Relação de encadeamento:
    • Exemplo: Regra "ReturnNumberOfStops" A regra de gatilho de ações then "ApprovedFlights"
  • Execução de RuleSet:
    • Exemplo: Regras: "Executando RuleSet FlightRuleSet"
  • Avaliação de condição:
    • Exemplo: Regras: Avaliando a condição na regra "SetDefaultScore"
  • Resultado da avaliação da condição:
    • Exemplo: Regras: condição avaliada como True
  • Execução da ação:
    • Exemplo: Regras: ações de avaliação THEN para a regra "SetDefaultScore"

Todas as mensagens de rastreamento estão definidas no momento no nível "Informações", portanto, você deve especificar um nível de Informações ou Detalhado no arquivo de configuração para ver o rastreamento de regras.

Conclusão

O WF fornece uma funcionalidade de regras flexíveis que pode ser aproveitada de várias maneiras diferentes para dar suporte a uma ampla gama de cenários. Desde condições de atividade simples até RuleSets de encadeamento avançado sofisticados, a tecnologia permite que você integre perfeitamente o suporte a regras em seus fluxos de trabalho. Além disso, o mecanismo de regras também pode ser aproveitado fora dos fluxos de trabalho para fornecer funcionalidade de regras a qualquer aplicativo .NET.

O conjunto de recursos permite que novos desenvolvedores incorporem facilmente regras simples em fluxos de trabalho, ao mesmo tempo em que fornecem a riqueza e a extensibilidade para dar suporte a cenários de aplicativos e RuleSets muito mais avançados. Este documento, combinado com os recursos citados na próxima seção, deve ajudar os desenvolvedores novos nas Regras do WF a aprender sobre a tecnologia e rapidamente se tornarem produtivos com seu uso.

Para obter mais informações

  • Site de fluxo de trabalho do MSDN

    Vários documentos e links para webcasts e laboratórios.

  • Exemplos de site da comunidade

    • Kit de ferramentas RuleSet externo – fornece um exemplo de como externalizar regras de assemblies de fluxo de trabalho.
    • Análise de Conjunto de Regras — uma ferramenta para analisar RuleSets para relações entre regras e entre regras e dados.
    • Regras no Excel – fornece um exemplo de como usar regras autônomas, fora de um fluxo de trabalho. Também demonstra como criar programaticamente regras criadas por meio de uma tabela de decisão no Excel.
  • Exemplos do SDK

    • IfElseWithRules — mostra o uso de uma RuleCondition em uma atividade IfElse (em \Technologies\RulesAndConditions).
    • DynamicUpdateChangingRules – demonstra o uso das APIs de atualização dinâmica para alterar uma RuleCondition em uma instância de fluxo de trabalho em execução (\Technologies\RulesAndConditions).
    • SimplePolicy – demonstra o uso das APIs para definir um RuleSet simples e uma atividade de política (\Technologies\Activities\Policy).
    • AdvancedPolicy – define um RuleSet mais complexo (\Technologies\Activities\Policy).
    • RuleActionTrackingEventSample — mostra como capturar resultados de avaliação de regra em um provedor de acompanhamento (\Technologies\Tracking).
  • Fórum de fluxo de trabalho do MSDN

    • Para perguntas relacionadas a Regras do WF ou WF em geral, visite este fórum de discussão.

 

Sobre o autor

Jurgen Willis é um Gerente de Programas da equipe do Windows Workflow Foundation responsável pela tecnologia do mecanismo de regras e atividades controladas por regras. Antes de ingressar na Microsoft, Jurgen projetou e implementou soluções de integração e gerenciamento de processos para empresas da Fortune 500.