Twitter
RSS

O uso do Reflection

0
Um dos maiores benefícios do .NET Framework e do Common Language Run-Time(CLR) em particular é a riqueza dos tipos de informações em runtime. O System.Reflection permite que você navegue e analise um tipo de dados em tempo de execução. Esta capacidade permite desenvolver sistemas mais dinâmicos e que possuam uma arquitetura modular mais clara.

Entre diversas outras funcionalidades, o Reflection nos pertime encapsular os assemblies. Com isso você pode utilizar o Reflection para acessar um assembly que não esteja diretamente referenciado em seu projeto, podendo obviamente, utilizar suas classes e métodos.

O uso mais comum, útil e prático de Reflection é a chamada de métodos dinâmicos, de um assembly externo ou não.

Veja no exemplo abaixo um código que usa Reflection para carregar a classe HttpUtility do assembly System.Web e usar os métodos HtmlEncode e HtmlDecode em um texto HTML:

'Código em VB.NET:
Imports System.Reflection

Public Class Program
   Public Overloads Shared Sub Main()
      Dim path As String = "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll"
      'Instancia o Assembly através do arquivo
      Dim webAssemby As Assembly = Assembly.LoadFile(path)
      'Recebe o tipo de objeto da classe HttpUtility
      Dim utilType As Type = webAssemby.GetType("System.Web.HttpUtility")
      'Recebe os método estáticos HtmlEncode e HtmlDecode
      Dim encode As MethodInfo = utilType.GetMethod("HtmlEncode", _
      New Type() {GetType(System.String)})
      Dim decode As MethodInfo = utilType.GetMethod("HtmlDecode", _
      New Type() {GetType(System.String)})
      'Cria uma string para codificar
      Dim originalString As String = "Isto é um exemplo do uso de Reflection <.>"
      Console.WriteLine(originalString)
      'Codifica e mostra o valor codificado
      Dim encoded As String = CType(encode.Invoke(Nothing, New Object() {originalString}), String)
      Console.WriteLine(encoded)
      'Decodifica para comparar se funcionou corretamente
      Dim decoded As String = CType(decode.Invoke(Nothing, New Object() {encoded}), String)
      Console.WriteLine(decoded)
   End Sub
End Class

//Código em C#:
using System;
using System.Reflection;

namespace ReflectionCSharp
{
   class Program
   {
       static void Main(string[] args)
       {
           String path = @"C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll";
           //Instancia o Assembly atrav‚s do arquivo
           Assembly webAssemby = Assembly.LoadFile(path);
           //Recebe o tipo de objeto da classe HttpUtility
           Type utilType = webAssemby.GetType("System.Web.HttpUtility");
           //Recebe os m‚todo est ticos HtmlEncode e HtmlDecode
           MethodInfo encode = utilType.GetMethod("HtmlEncode", new Type[] {typeof(System.String)});
           MethodInfo decode = utilType.GetMethod("HtmlDecode", new Type[] {typeof(System.String)});
           //Cria uma string para codificar
           String originalString = "Isto ‚ um exemplo do uso de Reflection <.>";
           Console.WriteLine(originalString);
           //Codifica e mostra o valor codificado
           String encoded = (String)encode.Invoke(null, new Object[] {originalString});
           Console.WriteLine(encoded);
           //Decodifica para comparar se funcionou corretamente
           String decoded = (String)decode.Invoke(null, new Object[] {encoded});
           Console.WriteLine(decoded);
        }
     }
}

É claro que o Reflection não faz apenas isso, possúi vários recursos interessantes, que vale a pena serem explorados. Mas uma coisa é inegável, as chamadas dinâmicas feitas com o Reflection tornam a lógica da sua aplicação bem mais flexíveis.

Até a próxima...

Builder

0
Definição: Separa a criação do objeto complexo da sua representação. O mesmo processo de construção pode criar diferentes representações.

As classes e/ou objetos que participam deste padrão são:

Builder (VeiculoBuilder) o especifica uma abstract interface para a criação das partes do objeto tipo Produto ConcreteBuilder (MotoBuilder, CarroBuilder, CaminhaoBuilder) o constrói e reúne partes do objeto Produto que implementa a interface Builder o define e marca a criação da representação do objeto o fornece uma interface para devolver um objeto do tipo Produto Director (Concessionaria) o constrói um objeto usando a
interface Builder Product (Veiculo) o representa o objeto complexo antes da construção. o incluí as classes que definen as partes que constituem o objeto, incluindo interfaces para reunir as partes no resultado final

Builder: Quando e onde usar?
O padrão Builder é um padrão de projeto de criação de objetos que permite o cliente contruir um objeto complexo especificando somente seu tipo e conteúdo. Os detalhes da construção são escondidos inteiramente do cliente. A motivação mais comum para usar o padrão Builder é para simplificar o code do cliente que cria objetos complexos. O Cliente pode apenas especificar as etapas que são necessárias para o Builder criar o objeto, sem ter conhecimento de como o trabalho atual é finalizado. Um cenário aonde você deve considerar o uso do padrão de projeto Builder é quando é deselvolvido um gerador de código. Você pode escrever uma aplicação que cria stored procedures para diferentes tipos de banco de dados(SQL Server, Oracle, DB2). A saída real é bastante diferente, mas as etapas para a criação dos procedimentos contidos no CRUD(Create, Read, Update, Delete) são todos muitos similares.

O padrão Builder não é amplamente usado, mas pode ser encontrado em duas classes do .NET Framework. VBCodeProvider e CSharpCodeProvider criam classes Builder através do método CreateGenerator. O método CreateGenerator retorna uma interface ICodeGenerator onde a geração do código fonte pode ser controlado.

Para ver um exemplo do design pattern Builder na prática é só baixar o projeto de exemplo que segue no link abaixo:
Exemplo padrão Builder (VS2008)

Até a próxima...