Neste artigo vamos expor algumas ideias sobre Windows Workflow Foundation e como este notável recurso está mudando pouco a pouco a maneira dos programadores.NET trabalharem.
No passado tínhamos ferramentas de processo para mapearmos atividades de maneira mais funcional e menos técnica. Já tínhamos também ferramentas de “Orchestration” como o BizTalk Server da Microsoft, onde já era possível criar em versões mais antigas, processos de negócio visando a interoperabilidade e troca de mensagens entre sistemas e aplicações de maneira dinâmica, conectando pontas de diferentes sistemas ou aplicações, facilitando assim a integração entre sistemas.
Bom, e onde entra o Workflow? Basicamente falando, desenhar um workflow no Visual Studio é uma experiência prática semelhante às estas ferramentas de BPEL, porém, com todo o poder, robustez e estabilidade do Visual Studio, aliado aos diversos recursos disponíveis na BCL do .NET Framework.
Iniciar o desenvolvimento de Workflows utilizando o Visual Studio já era possível com a versão 2005, com as extensões do WWF, inclusive a Microsoft disponibilizou suporte à BPEL com uma extensão BPEL para o Windows Workflow Foundation.
O que muda para os programadores e arquitetos?
Em essência, para os programadores que estão habituados a canais, fluxos de programação, interoperabilidade, camada de apresentação e todos estes paradigmas que utilizamos para representar parte do mundo real em um mundo sistêmico orientado a objetos e eventos, logo quando se deparar com um Workflow não estão muito errados se pensar: “ei, isto é semelhante à programação via código, não tenho muito porque me assustar quanto ao entendimento técnico”.
Hoje criamos bibliotecas de componentes e isto não muda muito: teremos bibliotecas de workflows. Deem uma olhada no meu novo projeto no CodePlex. Estou pregando o conceito de Workflow-DNA, onde você tem todas as suas operações corporativas mapeadas em Workflows, criando o que eu chamo de a identidade funcional da empresa. Assim, cada empresa é única em seus processos, como uma impressão digital.
O conceito de Workflows é bastante simples e é só se habituar a uma maneira de pensar onde você desenha processos e fluxos de trabalho e não sai mais codificando. Os workflows podem substituir quase, se não totalmente, toda a camada de regra de negócio, geralmente intitulada “Business Tier”, e ter importantes funções e outras camadas também. Os recursos encontrados no WWF são ótimos a ponto de podermos definir completamente como as telas da camada de apresentação devem ser sequenciadas. Sim, podemos colocar workflows em quase tudo!
Para exemplificar a utilização, vamos criar um workflow simples, mas completo no VS 2008 fazendo o seguinte:
- Solicitar ao usuário para entrar com sua idade;
- Processar a idade do usuário, decidindo a faixa etária;
- Responder ao usuário, baseado na idade respondida, qual é a faixa etária.
Para testar o projeto do artigo será necessário o Visual Studio 2008. Se você não o tem ainda pode baixar uma versão trial.
Task sequence brainstorming:
- Criar um projeto de “Workflow Activity Library” chamado Workflow.Library.Activities;
- Criar um projeto de “Sequential Workflow Console Application” chamado Workflows.Host;
- No projeto “Workflow.Library.Activities” criaremos três atividades customizadas:
- LerIdade
- ProcessarIdade
- EscreverResultado
- No projeto Workflows.Host criaremos um workflow e faremos com que as três atividades descritas no item “3” sejam totalmente integradas sequencialmente.
Iniciando a construção da aplicação
Para o item 1 da lista apresentada devemos iniciar o Visual Studio 2008 e criar um novo projeto do tipo Workflow Activity Library, como na Figura 1.
Nomeie este projeto como Workflow.Library.Activities. Nele criaremos os dois workflows customizados.
Para o item 2 da lista crie agora um projeto do tipo “Workflow Console Application” e nomeie-o como Workflows.Host, como na Figura 2.
O que teremos com a criação dos dois projetos deverá ser igual a Figura 3 a seguir, sem nenhuma customização ainda:
Já para o item 3 da lista criaremos três atividades customizadas para nosso workflow. Assim, adicione um item do tipo “Activity” e nomeie-o como LerIdade, conforme a Figura 4.
Agora repita os passos para criar a atividade “Leridade” e posteriormente as atividades ProcessarIdade e EscreverResultado.
Customizando a atividade “LerIdade”
Selecionando a atividade “LerIdade” arraste da Toolbar o item “CodeActivity” e nomeie esta atividade de código para LerIdadeDoConsole, semelhante à representação da Figura 5.
Dê um duplo-clique sobre o CodeActivity LerIdadeDoConsole e digite o código da Listagem 1.
private void LerIdadeDoConsole_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("Digite a idade:");
Idade = Console.ReadLine();
}
Antes de compilar será necessário criar um atributo chamado Idade, conforme a Listagem 2.
public string Idade{get;set;}
Simples não? Já criamos nossa primeira atividade e agora vamos para a segunda atividade.
Criando a atividade “Processa Idade”
O objetivo desta atividade é receber a idade digitada do console, e definir o valor de seu atributo “FaixaEtaria” com os textos “menor de idade”, “adulto”, “idoso”, tendo como base a idade digitada na primeira atividade.
Para isto, vamos começar escrevendo o atributo Idade, que terá suporte para “DataBinding” com expressões, configurado em tempo de design. Para isto vá para o código da atividade ProcessaIdade, criando sua Dependency Property, e o atributo digitando o seguinte código da Listagem 3.
public static DependencyProperty IdadeProperty =
System.Workflow.ComponentModel.DependencyProperty.Register("Idade",
typeof(string), typeof(ProcessarIdade));
[Description("Idade a processar")]
[Category("Custom Binding")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible]
public string Idade
{
get
{
return base.GetValue(IdadeProperty).ToString();
}
set
{
base.SetValue(IdadeProperty,value);
}
}
Como queremos que haja Binding e todas as facilidade de integração com outras atividades através de Binding Expressions, precisamos criar este código para que em tempo de design e execução o atributo seja acessado conforme precisamos. Observaremos que quando criamos atributos com a classe DependencyProperty da maneira como fizemos, eles podem ser configurados com o Assistente do Visual Studio.
No fluxo de trabalho para a Custom Activity de ProcessarIdade, precisamos fazer o seguinte:
- Se Idade < 18, atribuir FaixaEtaria=”MenorDeIdade”;
- Senão Se Idade <59, atribuir FaixaEtaria=”Adulto”;
- Senão se idade >=60, atribuir FaixaEtaria=”Idoso”;
O fluxo de trabalho visualmente terá a mesma aparência da Figura 6.
Todas as conditions utilizam Declarative Rule Condition para avaliar as expressões e “entender” o que fazer caso as condições sejam satisfeitas. As três “Conditions” serão configuradas da seguinte maneira:
- SeMenorDe18:
- Declarative Rule Condition
- Expressão: System.Convert.ToInt32(this.Idade) < 18
- SeAdulto:
- Declarative Rule Condition
- Expressão: System.Convert.ToInt32(this.Idade) <= 59
- SeNaoSeIdoso:
- Declarative Rule Condition
- Expressão: System.Convert.ToInt32(this.Idade) >= 60
A Policy AtribuiValorMenorDeIdade deve ser configurada da seguinte maneira:
- RuleSet name: AtribuiValorMenorDeidade
- Condition: True
- Then Actions: this.FaixaEtaria = “Menor de idade”
As duas atividades de “Code Activity”, AtribuiValorAdulto e AtribuiValorIdoso devem ter o código da Listagem 4 em seus eventos “ExecuteCodigo”.
private void AtribuiValorAdulto_ExecuteCode(object sender, EventArgs e)
{
this.FaixaEtaria = "Adulto";
}
private void AtribuiValorIdoso_ExecuteCode(object sender, EventArgs e)
{
this.FaixaEtaria = "Idoso";
}
Com isto terminamos a atividade customizada ProcessaIdade. Vamos criar agora a nossa última Custom Activity.
Criando a última atividade deste projeto: Atividade “EscreverResultado”
Esta atividade é tão simples quando à primeira e muito semelhante. Criaremos um atributo com recursos de “Binding” de expressões chamado “FaixaEtariaExibir”, e exibirá uma mensagem indicando qual a faixa etária.
Primeiro, vamos criar o atributo FaixaEtariaExibir e para isto precisamos criar sua Dependency Property e o atributo, com o seguinte código da Listagem 5.
public static DependencyProperty FaixaEtariaExibirProperty =
System.Workflow.ComponentModel.DependencyProperty.Register("FaixaEtariaExibir",
typeof(string), typeof(EscreverResultado));
[Description("Faixa etaria a exibir")]
[Category("Custom Binding")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible]
public string FaixaEtariaExibir
{
get
{
return base.GetValue(FaixaEtariaExibirProperty).ToString();
}
set
{
base.SetValue(FaixaEtariaExibirProperty,value);
}
}
Depois, vamos inserir uma “code activity” com o nome EscreverFaixaEtariaNoConsole, que terá seu evento “ExecuteCode” com a aparência da Listagem 6.
private void EscreverFaixaEtariaNoConsole_ExecuteCode(object sender, EventArgs e)
{
System.Console.WriteLine("A pessoa é: " + this.FaixaEtariaExibir);
System.Console.WriteLine("Pressione ma tecla para encerrar o Workflow...");
System.Console.Read();
}
Assim terminamos nosso componente Workflows.Library.Activities. Compile-o para se certificar que não há erros de build.
Vamos agora configurar o projeto Workflows.Host, o item 4 de nossa lista inicial. Primeiro renomeie o Workflow padrão de “Workflow1” para ProcessaIdade.
Ao abrir o workflow no designer, adicione uma referência para a biblioteca de atividades, a toolbar passa a apresentar as três novas atividades que criamos, conforme a Figura 7.
Dentro do seu workflow ProcessaIdade, coloque as três novas atividades na seguinte sequência:
- LerIdade
- ProcessarIdade
- ExcreverResultado
O workflow ficará com a aparência semelhante à Figura 8.
Agora configure os atributos das atividades da seguinte maneira:
-
Atividade processarIdadeActivity:
- Atributo Idade: ”Activity=lerIdadeActivity, Path=Idade”
-
Atividade escreverResultadoActivity
- Atributo FaixaEtariaExibir: “Activity=processarIdadeActivity, Path=FaixaEtaria”
Compile a solução utilizando CTRL + SHIFT + B e execute a solução com F5.
Observe que o fluxo será executado na sequência correta e será totalmente processado. A idade passou da primeira atividade para a segunda, a segunda atividade processou a idade, definindo uma faixa etária, e então a terceira atividade recebeu a faixa etária da segunda atividade, exibindo ao usuário o resultado.
Conclusão
Começar a criar Workflows é uma tarefa simples, embora tenhamos uma abordagem um pouco diferente da codificação tradicional, as vantagens em se utilizar workflows para construção de fluxos de trabalho é enorme. É possível extender bastante o sistema de workflows, criando novas atividades, regras, conectando workflows e fazendo com que eles interajam com o mundo externo sem maiores dificuldades.
Os Workflows vieram para facilitar nossa vida e é muito mais fácil e intuitivo termos diversos deles interconectados ou oferecendo serviços específicos, do que termos códigos densos e por natureza menos legível, se comparados à clareza por excelência dos Workflows.