NUGET – Equals entre objetos

Fala galera, tudo certo?

Depois de algum tempo sem postar nada no blog devido a falta de tempo estou retornando as atividade, neste post vou demonstrar um pacote que criei que imagino ajudar muita gente que necessita comparar dois objetos e validar o resultado, tanto para gerar logs ou mesmo até para bind de objetos.

A alguns dias no meu trabalho tive que gerar um log sobre campos que foram alterados por usuários por questão de segurança, utilizando o reflection criei alguns métodos para facilitar minha vida, ai veio a grande ideia, porque não compartilhar com todos, o objetivo nada mais é que você enviar dois objetos do mesmo tipo e o método lhe retorna as diferenças através de um dicionario de dados <string,string> ou senão um booleano com false para objetos com dados diferentes ou true para objetos com dados iguais.

O mesmo já se encontra no NUGET e pode ser baixado pelo comando abaixo através do prompt

Install-Package EqualsObject

ou pelo endereço

https://www.nuget.org/packages/EqualsObject/

Abaixo vou mostrar como utilizar o método, e vou colocar também no github para download a quem interessar.

1 – Criei 5 classes para gerar os testes, abaixo segue o código, nada mais é que classes com propriedades interligando uma a outra.

 

 [Serializable]
public class testeObjeto
{
public int Id { get; set; }
public string Nome { get; set; }
public string Endereco { get; set; }
public testeItem item { get; set; }
public List<Parametros> itTestes { get; set; }
}

[Serializable]
public class testeItem
{
public int Id { get; set; }
public string NomeItem { get; set; }
public subItem Subitem { get; set; }
}

[Serializable]
public class subItem
{
public int Id { get; set; }
public string NomeSubItem { get; set; }
}

[Serializable]
public class Parametros
{
public int Id { get; set; }
public string Descricao { get; set; }
public List<ParametrosTipo> Tipos { get; set; }
}

[Serializable]
public class ParametrosTipo
{
public int Id { get; set; }
public string DescricaoTipo { get; set; }
}

 

ok, agora vamos ao método simples para chamada do método do pacote, abaixo do código irei explicar os passos para a chamada do método, o que mais nos interessa

Somente lembrando, o projeto que utilizei para os testes foi um console application


class Program
{
static void Main(string[] args)
{
var tOrigem = new testeObjeto();
tOrigem.Id = 1;
tOrigem.Nome = "Vinicius";
tOrigem.Endereco = "rua teste, 200";
tOrigem.itTestes = new List<Parametros>() { new Parametros() { Id = 1, Descricao = "teste1" ,
Tipos = new List<ParametrosTipo>(){ new ParametrosTipo(){Id = 1, DescricaoTipo = "novo"} }
}, new Parametros() { Id = 2, Descricao = "teste2" } };
tOrigem.item = new testeItem() { Id = 1, NomeItem = "teste item 3", Subitem = new subItem() { Id = 1, NomeSubItem = "teste sub1" } };

var tNova = new testeObjeto();
tNova.Id = 1;
tNova.Nome = "Vinicius";
tNova.Endereco = "rua teste, 200";
tNova.itTestes = new List<Parametros>() { new Parametros() { Id = 1, Descricao = "teste1" ,
Tipos = new List<ParametrosTipo>(){ new ParametrosTipo(){Id = 1, DescricaoTipo = "novo"}}
}, new Parametros() { Id = 2, Descricao = "teste2" } };
tNova.item = new testeItem() { Id = 1, NomeItem = "teste item 3", Subitem = new subItem() { Id = 1, NomeSubItem = "teste sub1" } };

Console.WriteLine(new ObjectCompare.Equals().EqualsObject<testeObjeto>(tOrigem, tNova));

Console.WriteLine();

var ret = new ObjectCompare.Equals().EqualsObject<testeObjeto>(tOrigem, tNova, true);

foreach (DictionaryEntry iret in (IDictionary)ret)
{
Console.WriteLine(
string.Concat("Objeto -> ", iret.Key.ToString(), " Valor -> ", iret.Value.ToString()
)
);
}

Console.ReadKey();
}
}

Da linha 1 a 21 nada mais é que o abastecimento das propriedades para efetuar a comparação dos valores, mas estes podem ser objetos de seu projeto que queiram comparar, os objetos devem ser do mesmo tipo para a comparação.

Na linha 23 temos o primeiro exemplo de chamada do método

Console.WriteLine(new ObjectCompare.Equals().EqualsObject<testeObjeto>(tOrigem, tNova));

EqualsObject – Nome do metodo

<TesteObjeto> – Tipo do objeto a ser comparado

tOrigem – Objeto original – com os dados a serem comparados

tNova – Objeto cm dados alterados (ou não) que necessitam validação

Esta chamada de método retorna o parâmetro tipo booleano, conforme expliquei no inicio do post;

Já na linha 27 iremos nos deparar com uma nova chamada do método, agora esta chamada nos retorna o parâmetro do tipo dicionario<string,string>, os parâmetros de entrada são os mesmos citados no exemplo anterior, porém com mais um parâmetro do tipo booleano aprovando o retorno do tipo dicionario, pois o mesmo como default esta false;


var ret = new ObjectCompare.Equals().EqualsObject<testeObjeto>(tOrigem, tNova, true);

e por fim, criei neste exemplo uma exibição dos dados retornados no dicionario


foreach (DictionaryEntry iret in (IDictionary)ret)
{
Console.WriteLine(
string.Concat("Objeto -> ", iret.Key.ToString(), " Valor -> ", iret.Value.ToString()
)
);
}

e teremos o resultado conforme a figura abaixo e pronto sua comparação esta pronta.

Resultado

Pessoal espero que tenham entendido, e que utilizem a funcionalidade, caso tenham alguma duvida ou necessitem de auxilio na utilização deixem seus e-mails nos comentários que retorno assim que puder, criticas e sugestões são muito bem vindas.

GITHub do projeto de teste

https://github.com/viniciusrlopes/EqualsObjectTeste

Abraços a todos.

Vinicius.

 

 

Anúncios

Lista Genérica (Método Where) C#

Fala Galera,

Esta semana algumas pessoas vieram me questionar como utilizar o método “Where” de uma lista genérica, então resolvi criar este artigo e postar, sei que pode ser bastante útil a quem esta começando a programar em c# e/ou quer conhecer este método.

Pretendo depois que concluir o material de Reflection como havia prometido no post anterior, criar uma serie de artigos com os métodos que fazem parte de lista genérica, mas por hora segue o primeiro e não mais importante “Where”.

O que é Lista Genérica e o método Where.

Lista genérica é uma coleção de dados tipada que é de fácil manuseio e acesso através de seu índice.

Método “Where” representa um critério de pesquisa, como o utilizado no SQL, que restringe o resultado ao critério enviado.

Namespace da lista genérica é:

using System.Collections.Generic;

Exemplo

->  Primeiro passo, vamos abrir o Visual Studio;

->  Crie um novo projeto do tipo Console Application;

->  Crie uma pasta na solution com nome de “Model”, ela receberá todas as classes com as propriedades que iremos utilizar no exemplo;

->  Conforme a figura acima vamos criar uma classe com o nome de “entPessoa.cs”;

Para adicionar clique em cima da pasta com o botão direito, selecione Add/New Item;

Clique em Code/Class, altere o nome como mencionado acima;

->  Pronto, feito estes passos vamos programar.

Método de busca utilizando Lambda

->  Este método ira buscar os dados na lista que será passada por parâmetro e retornar o resultado se existente na lista.

Redigindo o método

 

->  Este método devera ser criado na classe principal do projeto, classe Program;


/// <summary>

/// Método de localização em lista utilizando Lambda

/// </summary>

/// <param name="pNome">Nome a ser pesquisado</param>

/// <param name="pListaPesquisa">Lista a ser pesquisada</param>

/// <returns></returns>

public static entPessoa[] LocalizaDadosListaComLambda(string pNome, List<entPessoa> pListaPesquisa) //Utilizando o Where

{

List<entPessoa> lRetorno = new List<entPessoa>(); //lista que será utilizada para retorno dos dados encontrados

//-------------------------------------------------------------------------------------------------------------------------------

//Lambda

//-------------------------------------------------------------------------------------------------------------------------------

IEnumerable<entPessoa> iPess = pListaPesquisa.Where(xPes => xPes.Nome == pNome); //Localiza na lista o nome passado pelo parâmetro pNome

foreach (entPessoa xEntPes in iPess) //Percorrendo a lista retorno com o nome passado pelo parametro

{

lRetorno.Add(xEntPes); //Adicionando os dados para a lista

}

//Outra forma de foreach direto da lista

pListaPesquisa.Where(xPes => xPes.Nome == pNome).ToList<entPessoa>().ForEach(

xFor =>

{

lRetorno.Add(xFor); //Este Foreach é mais simples de ser utilizado pois o mesmo é feito diretamente da lista de retorno do Where

//O resultado é o mesmo do foreach comum

}

);

//Ou senão simplesmente

return iPess.ToArray<entPessoa>(); //Retornando direto pelo Ienumerabla que criei acima ->

//IEnumerable<entPessoa> iPess = pListaPesquisa.Where(xPes => xPes.Nome == pNome);

//return lRetorno.ToArray<entPessoa>(); //Retornando a lista assinada dentro do método e adicionado através do foreach

}

è  Reparem que temos dois return, ambos retornarão o mesmo resultado porém com maneiras diferentes de gerar o retorno.

Método de busca utilizando Delegate

-> Notem que o processo é o mesmo que o com Lambda, porém utilizando o delegate como parte do processo;

Redigindo o método

</strong>

->  <strong>Este método devera ser criado na classe principal do projeto, classe Program;</strong>

/// <summary>

/// Método de localização em lista utilizando Delegate

/// </summary>

/// <param name="pNome">Nome a ser pesquisado</param>

/// <param name="pListaPesquisa">Lista a ser pesquisada</param>

/// <returns></returns>

public static entPessoa[] LocalizaDadosListaComDelegate(string pNome, List<entPessoa> pListaPesquisa) //Utilizando o Where

{

List<entPessoa> lRetorno = new List<entPessoa>(); //lista que será utilizada para retorno dos dados encontrados

//-------------------------------------------------------------------------------------------------------------------

//Delegate

//-------------------------------------------------------------------------------------------------------------------

IEnumerable<entPessoa> iPess = pListaPesquisa.Where(delegate(entPessoa xPess) { return xPess.Nome == pNome; }); //Localiza na lista o nome passado pelo parâmetro pNome

//Note que utilizei um delegate para esta função, você pode utilizar a forma que for mais familiar e mais fácil claro, porém o resultado é o mesmo.

foreach (entPessoa xEntPes in iPess) //Percorrendo a lista retorno com o nome passado pelo parâmetro

{

lRetorno.Add(xEntPes); //Adicionando os dados para a lista

}

//Outra forma de foreach direto da lista

pListaPesquisa.Where(xPes => xPes.Nome == pNome).ToList<entPessoa>().ForEach(

xFor =>

{

lRetorno.Add(xFor); //Este Foreach é mais simples de ser utilizado pois o mesmo é feito diretamente da lista de retorno do Where

//O resultado é o mesmo do foreach comum

}

);

//Ou senão simplesmente

return iPess.ToArray<entPessoa>(); //Retornando direto pelo IEnumerable que criei acima

//return lRetorno.ToArray<entPessoa>(); //Retornando a lista assinada dentro do metodo e adicionado através do foreach

}

<strong>

->  Concluído, agora vamos criar a classe entPessoa que será utilizada;

Código a ser utilizado na classe


public class entPessoa

{

#region Propriedades

private int _Id;

public int Id

{

get { return _Id; }

set { _Id = value; }

}

private string _Nome;

public string Nome

{

get { return _Nome; }

set { _Nome = value; }

}

private string _Endereco;

public string Endereco

{

get { return _Endereco; }

set { _Endereco = value; }

}

private string _Fone;

public string Fone

{

get { return _Fone; }

set { _Fone = value; }

}

#endregion

}

->  Agora já temos tudo criado conforme iremos utilizar, vamos então criar as chamadas dos métodos;

->  No método Main da classe principal adicione o código conforme a figura;

Redigindo o código


static void Main(string[] args)

{

string strNome = Console.ReadLine(); //Nome a ser pesquisado na lista, note que é somente uma demonstração, no cotidiano não será desta forma

//Abaixo criei uma lista e alguns dados para efetuar o teste com os métodos de pesquisa

List<entPessoa> lProcesso = new List<entPessoa>() { new entPessoa() { Id = 1, Nome = "Vinicius", Endereco = "Rua Sei lá", Fone = "25255252" },

new entPessoa() { Id = 1, Nome = "Nova Pessoa", Endereco = "Rua lá sei eu", Fone = "52522525" },

new entPessoa() { Id = 1, Nome = "Pessoa New", Endereco = "Rua bem distante", Fone = "88559988" }};

//Chamando os metodos de pesquisa e listando na tela

//Aqui vou já utilizar o foreach exibindo na tela os dados encontrados - Lambda

foreach (entPessoa xPess in LocalizaDadosListaComLambda(strNome, lProcesso))

{

Console.WriteLine(string.Concat("Lambda: ", xPess.Id, " - ", xPess.Nome)); //Listando o Id e o nome retornado pelo método com Lambda na tela

}

Console.ReadKey();

//Aqui vou já utilizar o foreach exibindo na tela os dados encontrados - Delegate

foreach (entPessoa xPess in LocalizaDadosListaComLambda(strNome, lProcesso))

{

Console.WriteLine(string.Concat("Delegate: ", xPess.Id, " - ", xPess.Nome)); //Listando o Id e o nome retornado pelo método com Delegate na tela

}

Console.ReadKey(); //Aguarda qualquer tecla ser precionada

}

->  Fechado, já temos os métodos de busca, a classe com as entidades e a chamada, agora é somente executar e ver o processo funcionar.

Galera se tiverem duvidas me enviem e-mails, entrem em contato comigo que na medida do possível ajudo a todos, abraços e bom estudo.

Vinicius.rodriglopes@gmail.com

Projeto de Exemplo ->

http://www.4shared.com/rar/4sNeJUBs/ListaGenerica.html

 

Trabalhando com Reflection em Dot.Net C# – Parte 1

Reflection com Dot.Net C#

Fala Galera,

Este é o meu primeiro post no blog, neste post quero mostrar a vocês o esquema de Reflection e algumas funcionalidades que dividirei em duas partes, a primeira mostrarei como persistir dados de uma classe a outra de maneira simples e no segundo como invocar métodos com e sem parâmetros.

Estou utilizando o VisualStudio 2010 e o Framework 4.0 com C#;

Entendendo um pouco sobre Reflection.

Reflection nada mais é que o espelho de classes, métodos, eventos que pode ser invocada de qualquer parte de seu sistema e a mesma sendo blindada ou não de forma dinâmica.

Quantas vezes você se deparou com uma DLL ou classe que necessita utilizar e não consegue gerencia-la pela forma usual, com o Reflection você consegue utiliza-la de uma forma gerenciada e invocar todos os métodos públicos e não públicos dinamicamente, inclusive as propriedades, fields e etc.

Qual a vantagem de utilizar o Reflection:

– Forma ágil de desenvolver uma aplicação;

– Forma dinâmica de invocar métodos e membros de uma classe ou DLL;

– Agilidade e facilidade para alteração e integração com novas regras;

A utilização do Reflection:

O Primeiro passo e o mais importante para iniciarmos o processo e a utilização da namespace Sytem.Reflection, esta por sua vez nos disponibilizara todos os métodos que englobam a reflexão, os métodos Types, Invokes, Gets e Sets e assim por diante.

Primeiro contato com o Reflection

Nesta primeira parte vamos fazer uma simples persistência para entender como funcionam alguns métodos do reflection.

Crie um novo projeto “Windows Forms Application” conforme figura 1.

Image

Figura 1

Depois de criado terá a tela conforme figura 2.

Image

Figura 2

No design do formulário inclua dois botões e um TextBox.

Image

Figura 3

Altere a propriedade do TextBox com nome de multiline para true, neste passo o TextBox passa a aceitar varias linhas como um memo.

Image

Agora vamos alterar os nomes dos botões e TextBox conforme figuras abaixo;

Botão 1 -> Name – btnBind

TextBox1 -> Name – mmRecepcao

Image               Image

Agora vamos adicionar algumas pastas e classes a nosso projeto.

Crie uma pasta chamada Model e uma Chamada Persistência conforme figura 5, e também 3 classes novas.

Na pasta Model Crie uma classe chamada Pessoa, do tipo publica.

Na Pasta Persistência cria duas classes com nomes csRecepcaoPessoa e csReflectionPersistencia.cs.

Na classe pessoa irão ficar as propriedades de onde irão surgir os dados para persistência.

Na Classe csRecepcao as propriedades que receberão os dados da classe pessoa.

Na Classe csReflectionPersistencia os métodos reflection.

Image

Figura 5

Agora vamos instanciar os namespaces em cada classe conforme figura 6, na classe do formulário adicione o Using wfReflection.Persistencia, local onde está a classe que iremos ter os métodos de persistência criados no processo anterior.

Image

Figura 6

Na classe csReflectionPersistencia iremos colocar o namespace using System.Reflection, essa responsável por todos os métodos do reflection.

Image

Volte a classe do formulário e vamos criar o evento onclick do botão btnBind, para fazer isso simplesmente vá no modo design do formulário e clique duas vezes em cima do botão, automaticamente ele ira te levar para classe do formulário já com o evento devidamente criado conforme figura abaixo.

Image

Feito isto agora vamos à classe pessoa que se encontra na pasta Model do projeto.

Crie as propriedades da classe desta forma

</pre>
public class Pessoa

{

#region Propriedades

public int _Id   { get;  set;  }

public string _Nome { get; set; }

public string _Sexo { get; set; }

public string _Endereco { get; set; }

#endregion

}

Image

Faremos a mesma coisa com a classe csRecepcaoPessoa.cs que esta na pasta Persistência

</pre>
public class csRecepcaoPessoa

{

#region Propriedades

public int _Id { get; set; }

public string _Nome { get; set; }

public string _Sexo { get; set; }

public string _Endereco { get; set; }

#endregion

}

Image

Pronto todas as propriedades devidamente criadas, vamos agora ao que interessa, vamos criar o método de persistência com reflection.

Vá até a classe csReflectionPersistencia.cs da pasta Persistência.

Crie um método chamado PersistePropriedades de forma static.

O método recebe dois métodos de entrada o pDe e pPara

pDe -> tipo object – Objeto da classe de remessa dos dados

pPara -> tipo ref object – Objeto de persistência dos dados, o mesmo será objeto referenciado devido a persistência

Ficara assim – public static void PersistePropriedades(object pDe, object pPara)

Agora vamos codificar o método conforme abaixo

</pre>
try

{

Type xTypeDe = pDe.GetType(); //Pegando o tipo e propriedades da classe objeto pDe

PropertyInfo[] xPropInfoDe = xTypeDe.GetProperties(); //Persistindo na variável tipo array de propertyinfo todas

//propriedades da classe pDe

Type xTypePara = pPara.GetType();

PropertyInfo[] xPropInfoPara = xTypePara.GetProperties();

foreach (PropertyInfo xPInfoDeIndividual in xPropInfoDe) //Varrendo em loop as propriedades da classe Pessoa através da variável xPropInfoDe

{

IEnumerable<PropertyInfo> xListaCamposPara = //Ienumerable que será responsável pela recepção da coleção de campos

xPropInfoPara.Where<PropertyInfo>(lC => lC.Name.Contains(xPInfoDeIndividual.Name)); //Buscando no array xPropInfoPara as propriedades que

//Contém o nome semelhante a classe pDe -> utilizei o lambda para a pesquisa, mas você pode utilizar a forma que achar melhor

//podendo ser através do foreach e com if comparar os nomes

foreach (PropertyInfo xPInfoParaIndividual in xListaCamposPara) //Varrendo em loop as propriedades do enumerable xListaCamposPara que foi

//Pesquisado os nomes semelhantes a classe Pessoa pDe

{

var ValorDeInserir = xPInfoDeIndividual.GetValue(pDe, new object[] { }); //Adicionando valor da propriedade da classe "pDe" xPInfoParaIndividual,

//para uma variavel generica para inserir na propriedade de classe "pPara"

ValorDeInserir = Convert.ChangeType(ValorDeInserir, xPInfoParaIndividual.PropertyType); //Convertendo o tipo de valor da propriedade "De" para o tipo

//da propriedade "pPara"

xPInfoParaIndividual.SetValue(pPara, ValorDeInserir, new object[] { }); //Inserindo o valor de "pDe" para "pPara"

//SetValue -> Responsável pela inserção dos dados no destino

//Parametros de entrada - SetValues

// 1º Paramentro -> Classe de destino, no nosso caso pPara

// 2º Parametro -> Valor a ser inserido

// 3º Parametro -> lista de objetos de parâmetro, neste caso poderemos usar como nulo mesmo

//SetValue e uma propriedade da variável de tipo PropertyInfo neste caso

}

}

}

catch (Exception ex)

{

throw ex; //Lançando a exceção

}

A figura abaixo ilustra como deve ficar.

Image

Depois de codificado vamos exibir os dados persistidos, abaixo vou mostrar o evento onclick do botão btnBind e o método de exibição no textbox nesta ordem.

</pre>
private void btnBind_Click(object sender, EventArgs e)

{

//Instanciando classe pessoa

Model.Pessoa csPessoa = new Model.Pessoa();

//Alimentando classe e propriedades de origem

csPessoa._Id = 1;

csPessoa._Nome = "Vinicius Lopes";

csPessoa._Sexo = "Masculino";

csPessoa._Endereco = "Rua bem longe";

//Instanciando classe de recepção dos dados

Persistencia.csRecepcaoPessoa csPessoaPersistencia = new csRecepcaoPessoa();

//Invocando método de persistência

csReflectionPersistencia.PersistePropriedades(csPessoa, csPessoaPersistencia);

//Método de exibição dos dados na tela

ExibeDadosPersistidos(csPessoaPersistencia);

}

Método de exibição dos dados, o mesmo deve ser criado na classe do formulário

</pre>
private void ExibeDadosPersistidos(object pPara)

{

csRecepcaoPessoa csPara = (csRecepcaoPessoa)pPara;

//Incluindo os dados da classe Para onde foi persistidos os dados no TextBox para visualização

mmRecepcao.AppendText(string.Concat(csPara._Id.ToString(), Environment.NewLine));

mmRecepcao.AppendText(string.Concat(csPara._Nome, Environment.NewLine));

mmRecepcao.AppendText(string.Concat(csPara._Sexo, Environment.NewLine));

mmRecepcao.AppendText(string.Concat(csPara._Endereco, Environment.NewLine));

}

A figura abaixo ilustra como deve ficar a classe do formulário.

Image

Galera espero que tenham conseguido pegar, ficou meio simplificado, porém creio que ficou de fácil entendimento, qualquer duvida me mandem e-mail que retorno a vocês, no próximo post irei ensinar o Invoke de métodos dinâmicos com Reflection e após vamos criar um projeto de cadastro completo somente utilizando Reflection.

Abraços

Vinicius

Vinicius.rodriglopes@gmail.com

Link Download Fonte Projeto – http://www.4shared.com/rar/OJ0d-xgQ/wfReflection.html

Iniciando trabalhos…

Bom dia galera, tudo bem?

Estou criando este blog para expor alguns trabalhos com Dot.Net C#, Delphi Prism, vou postar bastante coisa para que todos possam tirar duvidas, debater assuntos e ajudar a galera, espero que gostem dos posts.

Irei abordar bastante essas duas tecnologias mencionadas, primeiro assunto que vou tratar e o Reflection para ambos, pois percebo que na net esta dificil materiais legais para este assunto, estou terminando um mateiral e assim que concluido vou postar ok.

Abraços.