Artigo no estilo: Curso

Do que trata o artigo

Boas práticas, encapsulamento das validações de um determinado objeto utilizando o Validation Application Block da Microsoft.


Para que serve

Validação de objetos de forma a permitir reusabilidade entre componentes de uma aplicação e também suporte para validar entrada de informações em variados tipos de front-end.


Em que situação o tema é útil

Aplicações que necessitem validar objetos através de suas camadas mantendo um ponto único para configuração das regras de validação através de técnicas simples e de fácil manutenção.

Resumo do DevMan

Na segunda parte deste artigo veremos a integração do Validation Application Block com outros tipos de front-ends, como estendermos suas classes para criarmos validações mais complexas e específicas além da integração com outros blocos da Enterprise Library.

Na primeira parte do artigo foram apresentados problemas relacionados à entrada de dados em formulários e como o Validation Application Block pode auxiliar na elaboração de validações eficientes e flexíveis. Veremos agora como podemos estender o VAB para criarmos validações sofisticadas e também como podemos integrá-lo ao WCF (Windows Communication Foundation) aproveitando as facilidades de configuração além de outros conceitos desta biblioteca.

Nota do DevMan

A Microsoft Enterprise Library é uma coleção de componentes de software, chamados de application blocks, que podem ser reutilizados em vários aplicativos. Esses application blocks foram projetados para auxiliar os desenvolvedores nas rotinas comuns a qualquer sistema empresarial. Dentre essas rotinas temos log, validação, acesso a dados, controle de exceções e outras mais. Sua estrutura é formada para funcionar como um tipo de guia, que inclui código-fonte, casos de teste e documentação.

Recordando o cenário proposto

Na primeira parte do artigo foi proposto como cenário a construção de um formulário web para inscrição em um treinamento com os seguintes requisitos:

1. O participante deverá ter no mínimo 16 anos de idade;

2. O participante deverá informar um e-mail válido;

3. A data de inscrição será válida por um período predeterminado;

4. A inscrição será aberta em outros períodos durante o ano, por isso algumas configurações de validação devem ser criadas de forma a permitir uma fácil manutenção e flexíveis o suficiente para que sejam alteradas administrativamente, sem recodificação;

5. O participante poderá informar um número de voucher para ganhar um desconto na inscrição, este número precisará ser validado;

6. Futuramente a inscrição será disponibilizada em Windows Forms, e para tal, deseja-se manter as regras de validação centralizadas para fácil distribuição para interfaces de usuário distintas.

Uma solução contendo um projeto do tipo Web Application chamado NetMag.Validation.Web foi criada para disponibilizar o formulário de inscrição e todas as validações foram realizadas em outro projeto do tipo Class Library chamado NetMag.Validation.Entidades. O formulário tomou como base a classe ilustrada na Figura 1.

Figura 1. Diagrama da classe Participante

Nele o Validation Application Block foi aplicado utilizando atributos nos membros das classes, atendendo os requisitos 1 e 2 do cenário. Os itens 3 e 4 da lista de requisitos foram atendidos com as validações do VAB em arquivos de configuração, o que conferiu flexibilidade e independência de alterações no projeto que continha a classe Participante, além de permitir a utilização de uma ferramenta visual que acompanha a Enterprise Library para facilitar a tarefa. Para atendimento do requisito 6 foi apresentado a integração com Windows Forms, onde todas as definições realizadas até então foram aproveitadas. Continuando, veremos a seguir de que forma podemos atender o requisito 5.

Estendendo o Validation Application Block

Embora ofereça uma ampla variedade de validadores, o Validation Application Block cobre por padrão as situações mais comuns de validação. Mesmo oferecendo suporte à expressões regulares, podemos nos deparar com validações mais sofisticadas, como é o caso do requisito 5, proposto em nosso cenário de estudo. Nesse sentido, veremos como criar um validador customizado estendendo as classes do Validation Application Block, desta forma aproveitaremos o suporte aos diversos tipos de front-ends além das facilidades de configuração e os demais benefícios apresentados.

Criaremos duas novas classes responsáveis por estender o VAB, definindo um novo validador e um novo atributo. No projeto NetMag.Validation.Entidades (criado na primeira parte do artigo) crie uma nova classe conforme a Listagem 1, nomeie o arquivo como VoucherValidatorAttribute.cs.

Listagem 1. Classe VoucherValidatorAttribute, representa o novo atributo estendido da VAB

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using Microsoft.Practices.EnterpriseLibrary.Validation;
     5 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     6 
     7 namespace NetMag.Validation.Entidades.ValidadoresCustomizados
     8 {
     9     public class VoucherValidatorAttribute : ValidatorAttribute
    10     {
    11         protected override Validator DoCreateValidator(Type targetType)
    12         {
    13             return new VoucherValidator();
    14         }
    15     }
    16 }

Uma segunda classe deverá ser criada no projeto com o nome de arquivo VoucherValidator.cs e com o seu código idêntico à Listagem 2.

Listagem 2. Classe VoucherValidator, aplica as validações específicas do atributo estendido

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using Microsoft.Practices.EnterpriseLibrary.Validation;
     5 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     6 using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
     7 using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
     8 
     9 namespace NetMag.Validation.Entidades.ValidadoresCustomizados
    10 {
    11     [ConfigurationElementType(typeof(CustomValidatorData))]
    12     public class VoucherValidator : Validator
    13     {
    14         public VoucherValidator() : base(null, null) { }
    15 
    16         protected override string DefaultMessageTemplate
    17         {
    18             get { return "O voucher {0} é inválido"; }
    19         }
    20 
    21         protected override void DoValidate(
    22             object objectToValidate, 
    23             object currentTarget, 
    24             string key, 
    25             ValidationResults validationResults)  
    26         {
    27             if (!IsValidVoucher((string)objectToValidate))
    28             {
    29                 string message = string.Format(base.MessageTemplate, 
    30                     objectToValidate);
    31                 base.LogValidationResult(validationResults, 
    32                     message, currentTarget, key);
    33             }
    34         }
    35 
    36         private bool IsValidVoucher(string voucher)
    37         {
    38             /* Aqui definimos a lógica de validação
    39              * do Voucher, retornando "true" quando
    40              * todas as condições forem satisfeitas 
    41              * e "false" quando algum tipo de 
    42              * inconsistência for identificada. 
    43              */
    44             return true;
    45         }
    46     }
    47 }

A classe descrita na Listagem 1 permitirá utilizarmos um novo atributo chamado VoucherValidatorAttribute baseado no validador VoucherValidator, criado na Listagem 2. Basicamente, o novo atributo herda a classe ValidatorAttribute do Validation Application Block e sobrescreve o método DoCreateValidator, responsável por endereçar o validador a ser utilizado. Na Listagem 2 são declarados dois novos namespaces, sendo:

· Microsoft.Practices.EnterpriseLibrary.Common.Configuration: permite a configuração da classe via attribute.

· Microsoft.Practices.EnterpriseLibrary.Validation.Configuration: contém o tipo CustomValidatorData que será utilizado na validação.

Da linha 16 a 19 o método DefaultMessageTemplate é sobrescrito para que uma mensagem padrão apropriada seja definida para a validação do Voucher e utilizada em caso de inconsistência dos dados. Vale lembrar que essa mensagem pode ser modificada no momento que decorarmos o atributo Voucher da classe Participante com o novo validador customizado (veremos mais adiante como realizar essa tarefa). Esse método será utilizado apenas quando não informarmos alguma mensagem para o validador. Para que possamos customizar o tipo de validação realizada contra o Voucher informado devemos sobrescrever o método DoValidate (linhas 21 a 34), que recebe quatro parâmetros, conforme a Tabela 1.

Parâmetro

Finalidade

objectToValidate

Contém o valor passado no input que será validado.

currentTarget

Contém a classe alvo da validação, no nosso exemplo é a classe Participante.

Key

Indica qual atributo da classe será validado, no caso do nosso exemplo será o atributo Voucher.

validationResults

Armazena os resultados da validação.

Tabela 1. Parâmetros necessários para sobrescrever o método DoValidate

Ainda no método DoValidate da Listagem 2 realizamos as validações necessárias no método IsValidVoucher, criado para separar a lógica das validações específicas do voucher informado, e verificamos o seu retorno conforme podemos observar na linha 27. A propriedade MessageTemplate da classe base Validator recebe a mensagem apropriada (linha 29). Caso exista alguma inconsistência no voucher chamaremos o método LogValidationResult (linha 31) da classe base Validator, responsável por inserir novas entradas gravando os problemas encontrados nos dados recebidos. O retorno será computado no resultado geral das validações.

Com o validador criado devemos agora decorar o atributo Voucher da classe Participante conforme descrito na Listagem 3. É importante ressaltar que todas as facilidades do Validation Application Block serão aplicadas para o validador customizado da mesma forma que são para os validadores padrão.

Listagem 3. Aplicando o novo validator no atributo Voucher da classe Participante

    1 using System;
     2 using Microsoft.Practices.EnterpriseLibrary.Validation;
     3 using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
     4 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     5 using NetMag.Validation.Entidades.ValidadoresCustomizados;
     6 
     7 namespace NetMag.Validation.Entidades
     8 {
     9     public class Participante
    10     {
 ...
    31         [VoucherValidator]
    32         public string Voucher { get; private set; }
 ...
    58     }
    59 }

Como vimos na primeira parte do artigo podemos definir rulesets, agrupando as validações de forma a serem utilizadas apenas quando referenciadas explicitamente. As linhas 31 e 32 da Listagem 3 poderiam ser reescritas da seguinte forma:

   31         [VoucherValidator(
    32             MessageTemplate="Voucher inválido, favor solicitar um novo.", 
    33             Ruleset="ValidacaoAlternativa")]
    34         [VoucherValidator]
    35         public string Voucher { get; private set; }

Analisando as linhas 31 a 33 veremos que a mensagem padrão definida no método DefaultMessageTemplate da Listagem 2 será substituída pela nova mensagem definida pelo parâmetro MessageTemplate. Outra diferença é que este novo atributo faz parte de um grupo de validações definido no ruleset chamado ValidacaoAlternativa, sendo acionado somente quando informado na instanciação do validador.

Especificando regras de validação usando Self Validation

Outro recurso interessante do VAB é o chamado Self Validation, que deve ser usado sempre que queremos conferir validações realizadas pela própria classe, como por exemplo, uma validação de regra de negócio que pertença exclusivamente aos membros da classe. Em nosso exemplo poderíamos realizar uma validação adicional sobre o atributo Email verificando se ele pertence ao domínio @empresa.com.br. Para isso bastaria decorar a classe Participante com o atributo HasSelfValidation, como demonstrado na linha 9 da Listagem 4tence ao m.br ele foi informado com o domseir validaç validadore forma:eBlock serna listagem 4ipante , e criar um método conforme as linhas 41 a 51.

Listagem 4. Codificando a classe Participante com validações próprias

    1 using System;
     2 using Microsoft.Practices.EnterpriseLibrary.Validation;
     3 using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
     4 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     5 using NetMag.Validation.Entidades.ValidadoresCustomizados;
     6 
     7 namespace NetMag.Validation.Entidades
     8 {
     9     [HasSelfValidation]
    10     public class Participante
    11     {
 ...
    41         [SelfValidation]
    42         public void ChecaEmail(ValidationResults resultados)
    43         {
    44             if (Email.IndexOf("@empresa.com.br") > 0)
    45             {
    46                 string mensagem = "Não é permitido utilizar " +
    47                     " e-mail do domínio 'empresa.com.br'";
    48                 resultados.AddResult(new ValidationResult(mensagem,
    49                         this, "Email", "", null));
    50             }
    51         }
 ...
    72     }
    73 }

O atributo SelfValidation indicará para o VAB no momento que chamarmos o método Validate que a propriedade ChecaEmail deve ser executada, e caso exista alguma inconsistência, os resultados serão sumarizados no resultado global da validador, por isso a necessidade do parâmetro resultados do tipo ValidationResults (linha 42).

Validadores do tipo SelfValidation podem ser utilizados em conjunto com os demais validadores, sendo que o resultado das validações levará em consideração a soma dos resultados de todos os validadores existentes.

Integração com o WCF

O Validation Application Block é capaz de integrar-se ao WCF (Windows Communication Foundation) adicionando um comportamento personalizado, validando os parâmetros dos serviços através de uma extensão disponibilizada em uma de suas bibliotecas. Essa biblioteca permite que as mensagens sejam validadas, bem como contratos e parâmetros, como já mencionado.

Nota

O WCF já foi abordado em detalhes na .Net Magazine em edições anteriores e, por não ser o foco deste artigo, os passos para a integração como VAB serão mostrados através de um exemplo simples.

Crie na solução um projeto do tipo WCF Service Library, conforme ilustrado na Figura 2, dê o nome NetMag.Validation.WCF para este projeto.

Figura 2. Adicionando o projeto WCF para aplicação da integração com o VAB

Em seguida, adicione no projeto as referências para as bibliotecas a seguir:

· Microsoft.Practices.EnterpriseLibrary.Common.dll

· Microsoft.Practices.EnterpriseLibrary.Validation

· Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF

Estes arquivos estão disponíveis no diretório de instalação da Enterprise Library, que por padrão é C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin. Se tudo foi instalado corretamente eles vão também aparecer na lista de referências do Visual Studio, conforme a Figura 3. Adicione ao projeto WCF um novo arquivo de classe exatamente como descrito na Listagem 5.

Figura 3. Adicionando a referência do VAB para integração com o WCF

Listagem 5. Definindo os contratos do serviço de Inscrição através da interface IInscricao e a classe Funcionario

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Runtime.Serialization;
     4 using System.ServiceModel;
     5 
     6 using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
     7 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     8 
     9 namespace NetMag.Validation.WCF
    10 {
    11     [ServiceContract]
    12     public interface IInscricao
    13     {
    14         [OperationContract]
    15         bool ValidarAcessoInscricao(Funcionario funcionario);
    16     }
    17 
    18     [DataContract]
    19     public class Funcionario
    20     {
    21         [DataMember]
    22         public int Matricula { get; set; }
    23 
    24         [DataMember]
    25         public string Nome { get; set; }
    26     }
    27 }

Faremos como exemplo um serviço que validará se um usuário está habilitado para realizar a inscrição. Criaremos uma operação chamada ValidarAcessoInscricao que receberá como parâmetro um objeto do tipo Funcionario, definido nas linhas 19 a 26. Atente-se ao fato de que os namespaces Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF e Microsoft.Practices.EnterpriseLibrary.Validation.Validators devem ser adicionados para que possamos realizar os próximo passos (linhas 6 e 7).

Criaremos mais uma classe no projeto NetMag.Validation.WCF chamada Inscricao, que implementará a interface IInscricao, criada anteriormente. Neste exemplo estaremos realizando a validação da entrada de dados, no caso o objeto Funcionario. Portanto, as regras de negócio adicionais para validação do acesso do funcionário à inscrição serão omitidas, pois o mais importante agora é aprendermos como validar os valores enviados. Veja Listagem 6.

Listagem 6. Utilizando a interface do serviço WCF

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Runtime.Serialization;
     5 using System.ServiceModel;
     6 using System.Text;
     7 
     8 namespace NetMag.Validation.WCF
     9 {
    10     public class Inscricao : IInscricao
    11     {
    12         public bool ValidarAcessoInscricao(Funcionario funcionario)
    13         {
    14             /* Aqui será acrescentado o código
    15              * com as validações de acesso do
    16              * funcionário.
    17             */
    18             return true;
    19         }
    20     }
    21 }

Para que o VAB realize as validações contra os membros do serviço criado, vamos adicionar alguns atributos na interface IInscricao e na classe Funcionario, tomando a Listagem 5 como ponto de partida. A Listagem 7 apresenta o resultado final com todas as modificações necessárias para a integração do VAB com o WCF.

Listagem 7. Resultado final após a aplicação das validações usando a biblioteca de integração com WCF da VAB

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Runtime.Serialization;
     4 using System.ServiceModel;
     5 
     6 using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
     7 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
     8 
     9 namespace NetMag.Validation.WCF
    10 {
    11     [ServiceContract(Name="IInscricao")]
    12     [ValidationBehavior(RuleSet="Validar")]
    13     public interface IInscricao
    14     {
    15         [OperationContract(Name = "ValidarAcessoInscricao")]
    16         [FaultContract(typeof(ValidationFault))]
    17         bool ValidarAcessoInscricao(Funcionario funcionario);
    18     }
    19 
    20     [DataContract]
    21     public class Funcionario
    22     {
    23         [DataMember]
    24         [NotNullValidator(Ruleset="Validar")]
    25         [RangeValidator(100, 
    26             RangeBoundaryType.Inclusive, 200, 
    27             RangeBoundaryType.Inclusive, 
    28             MessageTemplate="A matricula deve ser um número entre 100 e 200",
    29             Ruleset = "Validar")]
    30         public int Matricula { get; set; }
    31 
    32         [DataMember]
    33         [NotNullValidator(Ruleset = "Validar")]
    34         [StringLengthValidator(6, 8, 
    35             MessageTemplate = "O login deve ter entre 6 e 8 caracteres",
    36             Ruleset = "Validar")]
    37         public string Login { get; set; }
    38     }
    39 }

Analisando o código da Listagem 7 veremos que na linha 12 foi adicionado o atributo ValidationBehavior, onde definiremos um contrato de comportamento de validação para processarmos todas as consistências desejadas, além disso, estaremos definindo uma ruleset chamada “Validar” (poderíamos definir tantas rulesets quanto fossem necessárias, adicionando novos atributos do tipo ValidationBehavior com as respectivas rulesets). Para distinguirmos no projeto cliente que consumirá o serviço WCF, um erro gerado pela execução de um método de outros erros iremos usar o atributo FaultContract, especificando-o com o tipo ValidationFault (classe pertencente à biblioteca de integração do VAB), conforme a linha 16. Para definirmos as validações da classe Funcionario, faremos exatamente da mesma forma que fizemos na primeira parte do artigo para a classe Participante, alterando apenas os tipos de validações aplicadas para o nosso exemplo. Da linha 24 a 29 e da linha 33 a 36 adicionamos os validadores tomando o cuidando de definir a mesma ruleset “Validar”, definida no atributo ValidationBehavior da interface IInscricao.

Os atributos ServiceContract, DataContract e DataMember são próprios do WCF e não devem ser modificados ou descartados.

O nosso serviço WCF está pronto para ser utilizado. Iremos agora adicionar uma referência no projeto NetMag.Validation.Web, clicando com o botão direito no projeto na janela Solution Explorer e escolhendo a opção Add Service Reference. Em seguida basta clicar no botão Discover para que seja adicionado no painel Services o serviço Inscricao, conforme ilustrado na Figura 4.

Figura 4. Adicionando a referência ao serviço WCF ValidarAcessoInscricao no projeto NetMag.Validation.WCF

Expanda o serviço e escolha no painel Operations o método ValidarAcessoInscricao, informe no campo Namespace o valor ServicoInscricao e para finalizar, clique no botão Ok. Adicione no projeto NetMag.Validacao.Web uma nova página com os controles indicados na Tabela 2. A nova página deve ser codificada exatamente como indicado na Listagem 8.

Tipo de controle

Propriedade

Valor

Label

ID

lblMatricula

Text

Matricula

TextBox

ID

txtMatricula

Label

ID

lblLogin

Text

Login

TextBox

ID

txtLogin

Button

ID

btnValidarAcesso

Text

ValidarAcesso

Label

ID

lblMensagemValidacao

Tabela 2. Controles e propriedades do formulário que invocará o serviço WCF

Listagem 8. Utilizando a interface do serviço WCF em uma página

    1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.ServiceModel;
     5 using System.Text;
     6 using System.Web;
     7 using System.Web.UI;
     8 using System.Web.UI.WebControls;
     9 
    10 using NetMag.Validation.Web.ServicoInscricao;
    11 
    12 namespace NetMag.Validation.Web.exemplos
    13 {
    14     public partial class Exemplo03 : System.Web.UI.Page
    15     {
    16         protected void Page_Load(object sender, EventArgs e)
    17         {
    18 
    19         }
    20 
    21         protected void btnValidarAcesso_Click(object sender, EventArgs e)
    22         {
    23             // Criando uma nova instância do serviço 
    24             InscricaoClient inscricao = new InscricaoClient();
    25             Funcionario funcionario = new Funcionario();
    26 
    27             funcionario.Matricula = Convert.ToInt32(txtMatricula.Text);
    28             funcionario.Login = txtLogin.Text;
    29 
    30             try          
    31             {
    32                 /* Executa o método de validação de acesso,
    33                  * o Validation Application Block irá validar
    34                  * a entidade Funcionario com as definições de
    35                  * validação no momento que o método
    36                  * ValidarAcessoInscricao for chamado.
    37                  */ 
    38                  
    39                 if (inscricao.ValidarAcessoInscricao(funcionario))
    40                 {
    41                     lblMensagemValidacao.Text = "Acesso válido.";
    42                 }
    43             }
    44             catch (FaultException ex)
    45             {
    46                 /* Para acessarmos os erros encontrados
    47                  * na validação devemos recuperar a exceção do tipo
    48                  * ValidationFault.
    49                  */
    50                 ValidationFault inconsistencias = ex.Detail;
    51 
    52                 StringBuilder resultado = new StringBuilder();
    53                 resultado.Append("Atenção!
");
    54                 resultado.Append("Os seguintes campos estão inconsistentes:

");
    55 
    56                 foreach (ValidationDetail validationResult in inconsistencias.Details)
    57                 {
    58                     resultado.Append(String.Format("- {0}
",
    59                         validationResult.Key.ToString()));
    60                     resultado.Append(String.Format("  {0} ",
    61                         validationResult.Message));
    62                     resultado.Append("

");
    63                 }
    64 
    65                 lblMensagemValidacao.Text = resultado.ToString();
    66             }
    67             finally
    68             {
    69                 inscricao.Close();
    70             }
    71         }
    72     }
    73 }

Note que o namespace System.ServiceModel será necessário para invocarmos o serviço WCF. No evento Click do botão btnValidarAcesso iremos realizar a chamada ao serviço criado, conforme as linhas 21 à 71. No momento que o método ValidaAcessoInscricao for chamado, as validações definidas no serviço através da interface IInscricao serão executadas.

Um detalhe importante é que para recuperarmos algum erro de consistência encontrado devemos tratar a exception do tipo FaultException – caso ocorra – e utilizarmos a classe ValidationFault para analisar as inconsistências encontradas. Isso só foi possível porque no exemplo da Listagem 7 adicionamos na linha 16 o atributo FaultContract indicando que seu tipo seria derivado da classe ValidationFault da VAB. Uma vez capturada, para exibirmos as mensagens contidas na Exception basta percorrer a coleção ValidationDetail.

O exemplo anterior requer que o método ValidarAcessoInscricao seja executado para que as validações ocorram, contudo, podemos nos deparar com uma situação onde seja necessário verificar o input informado para o objeto Funcionario antes de executarmos a operação. Para isso o Validation Application Block fornece um tipo de validação chamado Validation Parameter Inspector, que provê a validação de um parâmetro de uma classe através da descrição de sua operação.

Para entendermos melhor esse mecanismo vamos alterar o código da Listagem 8, modificando o evento Click do botão btnValidarAcesso para que fique conforme as linhas 34 à 81 da Listagem 9.

Listagem 9. Alterando a chamada para realizar a verificação através do ValidationParameterInspector

...
    23 
    24         public OperationDescription ObterOperationDescription(
    25             Type contractType,
    26             string operationName)
    27         {
    28             ContractDescription contract = new ContractDescription(contractType.Name);
    29             OperationDescription operation = new OperationDescription(operationName, contract);
    30             operation.SyncMethod = contractType.GetMethod(operationName);
    31             return operation;
    32         }
    33 
    34         protected void btnValidarAcesso_Click(object sender, EventArgs e)
    35         {
    36             InscricaoClient inscricao = new InscricaoClient();
    37 
    38             OperationDescription operation = 
    39                 ObterOperationDescription(typeof(NetMag.Validation.WCF.IInscricao),
    40                 "ValidarAcessoInscricao");
    41 
    42             ValidationParameterInspector validationInspector =
    43                 new ValidationParameterInspector(operation, "Validar");
    44 
    45             divAlerta.Visible = true;
    46 
    47             try
    48             {
    49                 Funcionario funcionario = new Funcionario();
    50                 funcionario.Matricula = Convert.ToInt32(txtMatricula.Text);
    51                 funcionario.Login = txtLogin.Text;
    52 
    53                 validationInspector.BeforeCall("ValidarAcessoInscricao", 
    54                     new object[] { funcionario });
    55 
    56                 lblMensagemValidacao.Text = "Acesso válido.";
    57 
    58             }
    59             catch (FaultException ex)
    60             {
 ...
    77             }
 ...
    82         }
    83     }
    84 }

Iremos adicionar um método para auxiliar-nos na obtenção da descrição da operação no qual os parâmetros precisam ser validados, exatamente como mostrado nas linhas 24 à 32 da Listagem 9. A classe ValidationParameterInspector do VAB permite acionar as validações definidas para a classe Funcionario sem que precisemos chamar o método ValidarAcessoInscricao, conforme linha 42, onde criamos uma variável do tipo ValidationParameterInspector passando a operação desejada e o ruleset apropriado. Nas linhas 53 e 54 chamamos o método BeforeCall passando o nome da operação e os dados de entrada informados.

Outros tipos de bibliotecas e extensões para o Validation Application Block

Por padrão o VAB permite a integração com Web Forms, Windows Forms e WCF, contudo, sendo a Enterprise Library um projeto aberto, membros das comunidades .NET desenvolveram novas bibliotecas que ampliam suas possibilidade de uso. A seguir citarei alguns exemplos:

· EntiLib Contrib – Projeto disponível no CodePlex contendo diversas extensões para as bibliotecas do Validation Application Block, disponível no link http://entlibcontrib.codeplex.com/.

· EntLib Extensions To WSSF – Projeto do CodePlex que disponibiliza bibliotecas para integração do Web Service Software Factory com a Enterprise Library. O pacote de extensões pode ser baixado através do link http://entlibextensionswssf.codeplex.com/.

· ASP.NET MVC Validation Library – Outro projeto do CodePlex que oferece validações para o ASP.NET MVC utilizando o Validation Application Block para endereçamento das validações server-side, disponível no link http://aspmvcvalidation.codeplex.com/.

Integração do Validation Application Block dentro da Enterprise Library

Os blocos existentes na Enterprise Library fazem uso de diversos padrões de projetos (também chamados de Design Patterns) como forma de garantir soluções concisas, com reutilização de sua arquitetura, design e implementação. Podemos destacar dentre esses padrões alguns mais relevantes, apresentados a seguir:

· Factory Pattern Fornece uma interface para criação de objetos correlatos ou dependentes sem a necessidade de especificar a classe concreta destes objetos.

· Plug-in Pattern – Esse padrão estende o comportamento de uma classe, permitindo que uma classe abstrata se conecte a ela, criando uma nova subclasse que inclui apenas as funções necessárias no contexto específico.

· Dependency Injection Pattern – Com esse padrão, é possível injetar as dependências de um determinado objeto e uma classe, em vez de depender dessa classe para criar o objeto. Esse padrão está relacionado com o padrão Inversion of Control Pattern.

Desta forma é possível combinar facilmente a utilização do Validation Application Block com outros blocos da Enterprise Library, como por exemplo, o Data Application Block, o Logging Application Block ou o Policy Injection Application Block. A Figura 5 ilustra as dependências entre os blocos disponíveis.

Figura 5. Diagrama de dependência entre os blocos da Enterprise Library

A instalação da Enterprise Library oferece uma série de projetos de exemplo utilizando os blocos nas mais variadas situações e contextos. É possível realizar o download de vários exemplos no formato Hands-on através do link http://tinyurl.com/entlibsamples.

Decidindo sobre o uso do Validation Application Block

Como foi apresentado neste artigo podemos endereçar a validação de objetos ao Validation Application Block com suporte aos front-ends mais comuns utilizados na plataforma .NET, de forma simples e concisa. Uma das vantagens de sua utilização é quando temos que replicar a lógica de validação em diversas camadas da arquitetura, contudo, em casos simples onde poucos objetos precisam ser validados o seu uso pode não ser adequado. Como alternativa nessas situações podemos, por exemplo, utilizar os controles de validação do ASP.NET ou do Windows Forms, sendo que para o WCF uma validação através de um esquema XML (XSD) pode ser uma alternativa apropriada.

Quando temos lógicas de validação que precisam ser reaproveitadas, o Validation Application Block é uma boa opção, pois além de permitir uma rápida programação das validações também disponibiliza meios de realizá-las através de arquivos de configuração, permitindo independência da aplicação e maior agilidade para ajuste das validações em determinados cenários.

Conclusão

Na segunda parte deste artigo entendemos como é possível estender o Validation Application Block para realizar validações sofisticadas, o que confere grande amplitude de reutilização de código. Apresentei a integração com o WCF com um exemplo prático para utilização de validações de membros da classe de serviço além de outras bibliotecas disponíveis no CodePlex para uso em conjunto.

Como mencionado na primeira parte do artigo, desenvolver aplicações confiáveis e seguras requer um considerável esforço, e a validação efetiva da entrada de objetos está intimamente ligada à qualidade de uma aplicação. Espero que este artigo tenha contribuído com informações e técnicas úteis para o desenvolvimento de suas aplicações, oferecendo uma alternativa efetiva de validação através do Validation Application Block. Até o próximo artigo!

Referências

Enterprise Library
http://msdn.microsoft.com/en-us/library/cc467894.aspx