C# - Usando Reflection (revisitado) - II
Neste artigo vamos recordar o conceito de Reflection e sua utilização na linguagem C# e o conceito de Late Binding. |
Quando desenvolvemos usando a linguagem C# especificamos os tipos de todas as suas variáveis, valores de retorno e parâmetros do método no código. O compilador verifica todos os tipos quando você constrói seu software e garante que você não tente inadvertidamente usar membros que não existam ou atribuíram um valor incorreto a um tipo. Isso é conhecido como Early Binding.
Na primeira parte do artigo recordamos o conceito e usamos como exemplo uma classe Cliente onde definimos métodos, construtores e propriedades e usando Reflection obtemos informações da classe usando o Early Binding.
Neste artigo vamos assumir que não temos conhecimento da classe Cliente em tempo de compilação.Neste cenário vamos obter as informações em tempo de execução usando o Late Binding.
Os tipos que estão vinculados tardiamente são verificados apenas quando são usados em tempo de execução. O Late Binding ou ligação tardia é ideal para criar software configurável, como aquele que possui um modelo de plug-in. Em tal software você pode permitir que o usuário especifique os nomes dos tipos e métodos a serem usados em um arquivo de configuração. O software usaria esses dados de configuração para carregar assemblies em tempo de execução, sem conhecimento prévio dos plug-ins ao escrever o aplicativo principal.
Recursos Usados:
Criando o projeto Console
Abra a solução CShp_Reflection criada no VS 2017 Community no artigo anterior.
Altere o código da classe Cliente incluindo o método GetNomeCompleto:
using static System.Console;
namespace CShp_Reflection
{
class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
public Cliente(int id, string nome)
{
this.Id = id;
this.Nome = nome;
}
public Cliente()
{
this.Id = -1;
this.Nome = string.Empty;
}
public void ImprimeID()
{
WriteLine($"ID = {this.Id}");
}
public void ImprimeNome()
{
WriteLine($"Nome = {this.Nome}");
}
public string GetNomeCompleto(string Nome, string Sobrenome)
{
return Nome + " " + Sobrenome;
}
}
}
|
Refatore o código do projeto definindo dois métodos :
No método ReflectionEarlyBinding() copie e cole o código existente no método Main().
No método ReflectionLateBinding() inclua o código a seguir:
static void ReflectionLateBinding() { // Carrega o assembly atual em execução como a classe Cliente Assembly assemblyEmExecucao = Assembly.GetExecutingAssembly(); // Carrega a classe CLiente para qual criamos a instância dinâmica // Cria a instância do tipo Cliente usando a classe Activator // Obtém informação de método usando o tipoCliente e GetMethod() // Invoca o método passando a instanciaCliente e os parâmetros |
Nesta classe temos :
1- A carga do assembly que contém a classe Cliente; no nosso caso, a classe Cliente esta presente no mesmo assembly que a classe Main, assim usamos: Assembly.GetExecutingAssembly(); para carregar o assembly em execução. Na classe Assembly existem diversos métodos estáticos que podemos usar para carregar um assembly em tempo de execução
2- A seguir carregamos a classe Cliente usando: assemblyEmExecucao.GetType("CShp_Reflection.Cliente"); Note que passamos o nome qualificado para o método GetType();
3- Criamos uma instância da classe Cliente dinamicamente usando : Activator.CreateInstance(tipoCliente);
Nota: A classe Activator permite criar tipos e instâncias usando late binding.
4- Agora que temos uma instância da classe Cliente podemos obter informação do método 'GetNomeCompleto' usando : tipoCliente.GetMethod("GetNomeCompleto");
5- O método GetNomeCompleto espera por dois parâmetros do tipo string, assim, criamos um array de strings e preenchemos com os valores para nome e sobrenome;
6- Finalmente invocamos o método passando a instância e array de parâmetros.
O código completo da classe Program após a refatoração ficou assim:
using System; using System.Reflection; using static System.Console; namespace CShp_Reflection static void ReflectionLateBinding() // Carrega a classe CLiente para qual criamos a instância dinâmica // Cria a instância do tipo Cliente usando a classe Activator // Obtém informação de método usando o tipoCliente e GetMethod() // Cria um array de parâmetros e preenche com nome e sobrenome // Invoca o método passando a instanciaCliente e os parâmetros static void ReflectionEarlyBinding() // Imprime os detalhes do Tipo // Imprime a lista de métodos WriteLine(); WriteLine(); |
Vimos assim as duas formas de obter informações de uma classe usando Reflection usando Early Binding e Late Binding.
A ligação tardia ou late binding é útil para ler as informações dos metadados de um assembly quando o tipo não é conhecido.
Pegue o projeto completo aqui: CShp_Reflection.zip
"E estava ali um homem que, havia trinta
e oito anos, se achava enfermo.Jesus disse-lhe: Levanta-te, toma o teu leito, e
anda.Logo aquele homem ficou são; e tomou o seu leito, e andava. E aquele dia
era sábado."
João 5:5-9
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET