Windows Workflow Foundation (WF) – Parte 2 – Xaml Workflows

Publicado em 14/01/2012

2


Olá pessoal. Tudo certo?!

No post anterior, mostrei como escrever fluxos muito simples em código. Obviamente, por mais interessante que seja o modelo de objetos do WF, tal abordagem faz pouco sentido visto que podemos escrever as mesmas rotinas, com mais simplicidade,diretamente em C#.

Nesse post, avançamos. Mostro como escrever os mesmos fluxos do post anterior usando Xaml. Dessa forma, começamos a identificar reais oportunidades de implementação “no mundo real”.

Algumas (poucas) palavras sobre Xaml

Xaml é uma linguagem declarativa, baseada em Xml. Embora tenha sido usada inicialmente nas implementações do WPF e do Silverlight, é uma abordagem extremamente eficiente para persistência de dados.

Windows Workflow Foundation permite que seus fluxos sejam persistidos e recuperados em formato Xaml.

Executando um fluxo definido em Xaml

A execução de fluxos armazenados em Xaml é bastante simples. Observe:

using System;
using System.Activities;
using System.Activities.XamlIntegration;

namespace XamlWorkflows
{
    class Program
    {
        static void Main(string[] args)
        {
            var wf = ActivityXamlServices.Load("workflow4.xml");
            WorkflowInvoker.Invoke(wf);

            Console.WriteLine("Press ENTER...");
            Console.ReadLine();
        }
    }
}

Para esse código funcionar, é necessário adicionar referências para System.Activities e System.Xaml.

Passemos, agora, a reproduzir os exemplos do post anterior usando somente Xaml.

Imprimindo algo na tela

Comecemos com um fluxo extremamente simples. Observe:

<WriteLine
  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  DisplayName="Hello World"
  Text="Hello World from Xaml WF" 
  />

Como havia mensionado, um fluxo precisa apenas de uma única atividade para funcionar.

Repare na relação direta entre os objetos e as propriedades destes com o Xaml. Lindo, não?!

Uma “sequência” de atividades

Já vimos como utilizar Xaml para definir uma atividade. Agora, um exemplo um pouco mais elaborado. Observe:

<Sequence DisplayName="Main Sequence"
  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <WriteLine 
    DisplayName="Hello World"
    Text="Hello World from Xaml WF" 
    />

  <WriteLine
    DisplayName="Print current hour"
    Text="[System.DateTime.Now.Hour.ToString()]"
    />
</Sequence>

Alguns pontos precisam ser destacados:

  • objetos conseguem definir uma “propriedade padrão” que será “alimentada” com o valor do nodo. Para o objeto  Sequence esta propriedade é Activities.
  • Valores entre colchetes “[]” são expressões Vb.

Variáveis

Como falado no post anterior, workflows têm variáveis para manutenção do estado do fluxo. Considere:

<Sequence DisplayName="Main Sequence"
  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Sequence.Variables>
    <Variable x:TypeArguments="x:Int32" Default="[DateTime.Now.Hour]" Name="hour" />
  </Sequence.Variables>
  <WriteLine 
    DisplayName="Hello World"
    Text="Hello World from Xaml WF" 
    />

  <WriteLine
    DisplayName="Print current hour"
    Text="[hour.ToString()]"
    />
</Sequence>

Da mesma forma que no exemplo “em código” definimos as variáveis no início do fluxo. Depois, utilizamos as mesmas normalmente em nossas expressões Vb.

Condicionais

Como indicado no post anterior, condicionais são atividades comuns. Observe:

<Sequence DisplayName="Main Sequence"
  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Sequence.Variables>
    <Variable x:TypeArguments="x:Int32" Default="[DateTime.Now.Hour]" Name="hour" />
  </Sequence.Variables>
  <WriteLine 
    DisplayName="Hello World"
    Text="Hello World from Xaml WF" 
    />

  <WriteLine
    DisplayName="Print current hour"
    Text="[hour.ToString()]"
    />

  <If Condition="[hour &lt; 12]">
    <If.Then>
      <WriteLine Text="Bom dia"/>
    </If.Then>
    <If.Else>
      <WriteLine Text="Boa tarde"/>
    </If.Else>
  </If>
</Sequence>

Lindo não?! Começa a fazer sentido converter operações em objetos serializáveis!?

Loops

Para concluir, vamos reproduzir nosso exemplo com loops,  agora em Xaml.

<Sequence DisplayName="Main Sequence"
  xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Sequence.Variables>
    <Variable x:TypeArguments="x:Int32" Default="[DateTime.Now.Hour]" Name="counter" />
  </Sequence.Variables>
  
  <WriteLine 
    DisplayName="Hello World"
    Text="Hello World from Xaml WF" 
    />

  <WriteLine
    DisplayName="Print current hour"
    Text="[counter.ToString()]"
    />

  <If Condition="[counter &lt; 12]">
    <If.Then>
      <WriteLine Text="Bom dia"/>
    </If.Then>
    <If.Else>
      <WriteLine Text="Boa tarde"/>
    </If.Else>
  </If>
  
  <While Condition="[counter > 0]">
    <Sequence>
      <WriteLine Text="[counter.ToString()]"/>
      <Delay Duration="00:00:01"/>
      <Assign>
        <Assign.To>
          <OutArgument x:TypeArguments="x:Int32">[counter]</OutArgument>
        </Assign.To>
        <Assign.Value>
          <InArgument x:TypeArguments="x:Int32">[counter - 1]</InArgument>
        </Assign.Value>
      </Assign>
    </Sequence>
  </While>
  
</Sequence>

Aqui entre nós… Tirando a mudança de valor da variável do fluxo, tudo é muito simples.

Então, o que achou!?

Era isso!

Smiley piscando

Etiquetado:
Publicado em: Post