Func, Action e Predicate

C sharp

Agora que já entendemos o funcionamento de um delegate, chegou a hora de falar dos seus irmãos mais novos.

Com o objetivo de ser um tipo especifico de delegate pré moldados para as situações mais comuns o .net criou esses tres tipos, Action, Func e Predicate, apesar de serem baseados no delegate, eles são especializações focadas em diferentes situações.

Action

Introduzido no Framework 2.0, Action é uma especialização do delegate focada em funções sem retorno com até 16 parâmetros.

O objetivo é poupar de criar um delegate especifico para essas situações, com isso em vez de ter que compartilhar a assinatura do nosso delegate com todos os pontos do sistema podemos simplesmente trabalhar com uma action de forma genérica.

Situado dentro da namespace System, a classe Action possui 17 sobrecargas diferentes, que vão de zero a 16 parâmetros, cobrindo a maioria das situações! (se a sua função tiver mais que 16 parâmetros provavelmente você tem sérios problemas de arquitetura ;) )

Exemplo:

public void ShowMessageInPortuguese(string s1, string s2)
{
  Console.WriteLine("Bem vindo " + s1 + " e " + s2);
}

public void Main()
{
  //Declaração de um Action que espere 2 parâmetros do tipo string
  Action<string, string> actionShowMessage;
	
  //Podemos declarar essa função utilizando lambda
  actionShowMessage = (s1, s2) => {Console.WriteLine("Hello " + s1 + " and " + s2);}; 
	
  //Ou usando um método concreto com a assinatura compatível
  actionShowMessage += ShowMessageInPortuguese;
	
  //Executando as 2 actions atribuídas ao mesmo tempo
  actionShowMessage("Rafael","Orion"); 
  /*Resultado:
    Hello Rafael and Orion
    Bem vindo Rafael e Orion
  */

  //Declarando uma action sem parâmetros
  Action welcomeAction;

  //Atribuindo um comportamento à action
  welcomeAction = () => Console.WriteLine("Welcome!");

  //Executando a action
  welcomeAction(); //Welcome!
}

Assim como um Multicast Delegate (delegate sem retorno), podemos encadear múltiplos métodos na mesma action como vimos no exemplo acima.

Predicate

Introduzido no Framework 2.0, O predicate, é uma especialização do delegate focada em funções com retorno booleano e que pode receber somente 1 valor como parâmetro, geralmente utilizado para critérios de validação.

Exemplo:

class Usuario
{
	public int Id { get; set; }
	public string Nome { get; set; }
	public string Email { get; set; }
	public bool Ativo { get; set; }
}

public void Main()
{
  var lista = new List<Usuario>(){
    new Usuario(){Id=1, Nome="Usuario 1", Email="u1@teste.com", Ativo=true},
    new Usuario(){Id=2, Nome="Usuario 2", Email="u2@teste.com", Ativo=false},
    new Usuario(){Id=3, Nome="Usuario 3", Email="u3@teste.com", Ativo=true},
    new Usuario(){Id=4, Nome="Usuario 4", Email="u4@teste.com", Ativo=false},
    new Usuario(){Id=5, Nome="Usuario 5", Email="u5@teste.com", Ativo=true},
    new Usuario(){Id=6, Nome="Usuario 6", Email="", Ativo=true},
    new Usuario(){Id=7, Nome="", Email="Usuario 7", Ativo=true},
    new Usuario(),
    new Usuario(){Id=-2, Nome="Usuario -2", Email="aaa", Ativo=true},
    null
  };

 //Criando um predicate que recebe um usuário como parâmetro e retorna um bool informando se é valido ou não
 var predicateValidUser = new Predicate<Usuario> (u =>
		u != null &&
		u.Id > 0 &&
		!string.IsNullOrEmpty(u.Nome) &&
		!string.IsNullOrEmpty(u.Email)
	);

	//Aplicando 0 predicate para filtrar os dados
	var usuariosFiltrados = lista.Where(usuario => predicateValidUser(usuario)).ToList();
	
	//Utilizando uma action para exibir o resultado
	usuariosFiltrados.ForEach (ShowActiveUsers);
	
  //ou
	usuariosFiltrados.ForEach (usuario =>
	{
		if (usuario.Ativo)
		{
			Console.WriteLine ($"({usuario.Id}) {usuario.Nome} <{usuario.Email}>");
		}
	});

}

void ShowActiveUsers (Usuario usuario)
{
	if (usuario.Ativo)
	{
		Console.WriteLine ($"({usuario.Id}) {usuario.Nome} <{usuario.Email}>");
	}
}

Func

Introduzido no Framework 3.5, Func é uma especialização do delegate focada em funções com retorno e até 16 parâmetros.

Assim como o Action e o Predicate os parâmetros não necessariamente precisam ser todos do mesmo tipo.

No caso da Func, o primeiro tipos especificado obrigatoriamente será o retorno da função, e os demais os parâmetros que serão recebidos, no exemplo abaixo nossa func irá retornar um valor do tipo int e irá receber 2 valores, sendo o primeiro do tipo string e o segundo do tipo bool.

Func<int, string, bool> myFunc;

Exemplo:

void Main()
{
  //Declara uma func que recebe 2 strings e retorna uma string
  Func<string,string, string> funcComparation;
	
  //Atribui um método concreto a func
  funcComparation = ShowLongest;
	
  //executa a func
  var result = funcComparation("Rafael", "Orion");
	
  Console.WriteLine(result); //Rafael
}

string ShowLongest(string value1, string value2)
{
  return value1.Length > value2.Length? value1: value2;
}

Delegate, Action, Func, Predicate … Qual devo usar?

Como podemos ver os quatro são bem parecidos, basicamente o delegate seria a forma mais genérica e abrangente, ja o action, func e predicate seriam um delegate pronto, cada um focado em uma situação especifica.

  • Delegate: É a assinatura de uma função que pode receber diferentes implementações, podendo receber parâmetros e retornar ou não valores.
  • Func: É um tipo de delegate, obrigatoriamente retornando algum valor e podendo ter de 0 a 16 parâmetros
  • Action: Seria equivalente a uma Func porém obrigatoriamente sem retorno
  • Predicate: Seria equivalente a uma Func mas que recebe somente um parâmetro e obrigatoriamente deve retornar um valor booleano

Ok, mas se o delegate já pode fazer tudo isso, porque utilizar func, action ou predicate?

Assim como podemos somente usar um if comum em vez de um if ternário, array em vez de list ou ate mesmo usar um while em vez de for, o que nos leva a fazer essas escolhas seria deixar o nosso código mais claro e objetivo.

Func, Action e Predicate são especializações do delegate para fins específicos.

Se eu tenho uma função que irá receber um delegate para executar uma validação e sei que o resultado sera true ou false, porque não usar direto o predicate, isso já comunica de cara a nossa intenção, alem de poupar algumas linhas declarando a estrutura do nosso delegate.

O mesmo vale para func e action, sem falar que muitas partes do framework como um simples foreach esperam esses tipos de dados, isso já seria um bom motivo para aprender seu funcionamento. ;)

O intuito é deixar os delegates para as situações mais especificas que não podem ser resolvidas utilizando action, func e predicate.

Espero que tenha ficado claro, sei que de cara não parece muito simples, mas recomendo fazer alguns testes com eles que garanto que irão facilitar muito sua vida. =)

Até a próxima.

Usando Extension Methods em c#

Extension Methods

Métodos de extensão são um recurso muito interessante para estendermos alguma classe já existente, independente dela ter sido criada por nós mesmo, uma biblioteca de terceiros ou até mesmo da própria microsoft.

Imagino que a maioria dos devs já passou pela situação de utilizar alguma biblioteca e pensar “nossa bem que podia ter uma função X aqui!”.

Mas porque não voce mesmo extender essa biblioteca para atender todas as suas necessidades hem?

Vamos direto ao exemplo!

void Main()
{
  var teste = "Rafael".GerarTag();
  Console.WriteLine(teste); //<Rafael />

  var teste2 = "Rafael".GerarTag("Orion"); //<Rafael>Orion</Rafael>
  Console.WriteLine (teste2);
}


public static class HtmlExtension
{
  public static string GerarTag (this string value)
  {
    return "<" + value + " />";
  }

  public static string GerarTag (this string value, string value2)
  {
    return "<" + value + ">" + value2 + "</" + value + ">" ;
  }
}

No exemplo acima criamos 2 métodos que estendem a classe string transformando um texto em uma tag html.

Desde que a HtmlExtension esteja na mesma namespace ou a referencia ao namespace esteja adicionada, qualquer strings terá esses 2 novo métodos disponíveis, parece até magica. ;)

Para criar uma classe de extensão precisamos seguir algumas regrinhas simples, primeiramente a classe e os métodos devem ser do tipo static.

Mas oq transforma efetivamente o método estático em uma extensão é o uso do this localizado no primeiro parâmetro da função.

public static string GerarTag (this string value)

No exemplo acima, como o this está antes do parâmetro do tipo string, isso indica que ele será uma extensão da classe string, nesse caso como só temos um único parâmetro que faz a referencia para a base da nossa extension, na hora do uso não será necessário passar nenhum parâmetro, pois o this indica que o valor da própria variável será utilizado para popular esse parâmetro automaticamente.

public static string GerarTag (this string value, string value2)

Nesse caso, além da referencia para a nossa extension temos mais um parâmetro, somente o segundo parâmetro será necessário durante o uso conforme os exemplos anteriores.

Bem simples não? a mesma lógica vale para qualquer tipo de classe até mesmo as suas próprias classes.

Até a próxima.

Referências:

Anonymous type, Dynamic e Object

Anonymous type

Anonymous Type

Os Tipos anônimos são utilizados para encapsular propriedades em um objeto somente leitura.

Introduzidos no c# 3.0 junto com o var, com ele podemos criar um objeto definindo diretamente no construtor as propriedades que queremos, sem precisar usar uma classe já existente.

Para instanciar um objeto do tipo anonimo o processo é similar a de uma classe comum, porem omitimos o tipo do objeto como no exemplo a seguir:

var produto = new { Nome= "Teclado", Descricao="Keychron K8", Preco = (decimal)69.00 };

Console.WriteLine("Produto " + produto.Nome + " " + produto.Descricao);

Bem simples não é verdade?

Note que não temos nenhuma classe com as definições do nosso produto, todos os campos foram definidos e os valores atribuídos diretamente no momento da instância.

Como os tipos anonimos são readonly nao podemos alterar o valor de nenhuma das propriedade, isso resultaria em um erro de compilação.

Object x Dynamic x var x Anonymous Type

Uma confusão bem comum é com relação aos tipos anonimos, dynamic e object, para quem ainda não tem esses conceitos bem definidos pode parecer que é tudo igual, então vamos tentar esclarecer um pouco.

Object

Introduzido no c# 1.0, o tipo object pode receber qualquer tipo de valor, já que todas as classes em .Net herdam do tipo object.

Por se tratar de um tipo, pode ser declarado sem receber nenhum valor inicial, porem mesmo aceitando qualquer tipo de valor, quando utilizado precisamos fazer cast para o tipo desejado.

uma variável do tipo object alem de poder receber qualquer valor, também pode alterar entre valores de diferentes tipos a qualquer momento.

exemplo:

object obj = "Rafael Orion"; //Declarando e iniciando uma variável object recebendo uma string
obj = 35; //sobrescrevendo o valor inicial com um valor do tipo inteiro

int number1 = obj; // compile error
int number2 = (int)obj; // correct

Note que apesar da nossa variável estár com um valor inteiro, não é possível utilizar ele como inteiro sem efetuar a conversão antes, isso irá gerar um erro de compilação.

Var

Introduzido no c# 3.0, o var nada mais é do que uma forma de declarar alguma variável sem informar diretamente o seu tipo, o tipo será deduzido baseado no valor recebido, por conta disso o valor da variável sempre deve ser informado no momento da declaração.

Diferente do object, dynamic e anonymous type, o var não é um tipo de valor, e sim somente uma forma de declarar os objetos, apesar de não obter nenhum ganho de performance na sua utilização ele é considerado por muitos uma boa pratica por deixar o código um pouco mais limpo e menos redundante. Exemplo:

Usuario usuario1 = new Usuario();
var usuario2 = new Usuario();

Note que em ambos os casos estamos instanciando um objeto do tipo “Usuario”, porem utilizamos o var não temos a redundância de informar o nome da classe duas vezes.

Justamente por não ser um tipo, e sim somente um atalho para definir o tipo por Inferência, quando utilizado o var a variável receberá o tipo do valor que está recebendo, e por conta disso não pode ser alterado posteriormente.

exemplo:

var obj = "Rafael";
obj = "Rafael Orion";
obj = 35; // compile error

No exemplo acima nossa variável obj será do tipo string por conta do valor que está sendo atribuído, se tentarmos atribuir um valor de um tipo diferente do inicial teremos um erro de compilação.

Anonymous Type

Introduzido no c# 3.0, como explicado anteriormente, podemos criar um objeto dinamicamente sem a necessidade de uma classe prévia que contenha a estrutura desejada.

Para declarar um anonymous type precisamos utilizar o var, já que não temos uma palavra reservada especificamente para esse tipo.

Dynamic

Introduzido no c# 4.0, e similar ao tipo object, com o dynamic podemos receber qualquer valor de forma bem flexível com a vantagem do cast ser feito automaticamente.

dynamic obj = "Rafael Orion";
obj = 35;
int number1 = obj; // correct
int number2 = (int)obj; // correct

Isso só é possível pois diferente do tipo object, dynamic não possui todas as informações sobre o valor recebido, algumas só serão resolvidas em runtime.

O fato de não ser fortemente tipado pode deixar o seu uso mais prático, porem pode ocultar alguns problemas que só iram explodir em runtime. como dizia o tio Ben, “Com grandes poderes vêm grandes responsabilidades” .

Exemplos:

var usuario = new { Id= 1, Nome = "Rafael", Profissao= "Programador"}; //Anonymous Type 
usuario.Nome = "Orion";  // compile error

//Verificando o tipo da nossa variável
Console.WriteLine(usuario.GetType().Name); //<>f__AnonymousType0`3

Console.WriteLine ("dynamic:");
dynamic obj1 = 1;
dynamic obj2 = "Orion";
dynamic obj3 = usuario;

Console.WriteLine(obj1.GetType().Name); //Int32
Console.WriteLine(obj2.GetType().Name); //String
Console.WriteLine(obj3.GetType().Name); //<>f__AnonymousType0`3

object obj4 = 1;
object obj5 = "Orion";
object obj6 = usuario;

Console.WriteLine("objects:");
Console.WriteLine (obj4.GetType().Name); //Int32
Console.WriteLine (obj5.GetType().Name); //String
Console.WriteLine (obj6.GetType().Name); //<>f__AnonymousType0`3

var obj7 = 1;
var obj8 = "Orion";
var obj9 = usuario;

Console.WriteLine ("var:");
Console.WriteLine (obj7.GetType().Name); //Int32
Console.WriteLine (obj8.GetType().Name); //String
Console.WriteLine (obj9.GetType().Name); //<>f__AnonymousType0`3
		

Como passar um tipo anonimo via parâmetro?

Se quisermos passar um tipo anônimo como parâmetro em alguma função precisamos utilizar o tipo dynamic, apesar do tipo object também suportar um tipo anonimo não teremos acesso as propriedades diretamente sem efetuar um cast para dynamic ou utilizando reflection, por conta disso o dynamic se encaixa melhor na situação.

exemplo:

void Main()
{
  var usuario = new { Id= 1, Nome = "Rafael", Profissao= "Programador"};
  Teste(usuario);
}
public void Teste(dynamic usuario)
{
  Console.WriteLine(usuario.Nome);
}

Como podemos ver a união do var com Anonymous Type e dynamic podem formar uma combinação muito poderosa e flexível. =)

Até a próxima.

Referências:

Generics em C#

Generics em c#

Conforme vamos avançando no entendimento de uma linguagem começamos a ter contato com alguns conceitos que no primeiro momento podem parecer complicados, mas são a chave para resolver diversos problemas.

Introduzido no .net Framework 2.0, o generics apresenta o conceito de parâmetros de tipo, onde em vez de usar um tipo fixo, podemos receber o tipo via parâmetro, deixando assim o nosso código mais flexível.

Pode parecer complexo mas até mesmo quem não está familiarizado com o termo generics já deve ter esbarrado com ele em algum momento, nem que seja na hora de declarar uma bela lista de string usando:

var lista = new List<string>;

Representado geralmente (mas não obrigatoriamente) pelo carácter T, o Generics pode ser usado tanto diretamente no método como na classe para um escopo mais abrangente.

Temos a possibilidade de criar classes e métodos que adiam a especificação de um ou mais tipos até que a classe seja instanciada ou o método utilizada, uma das características do Generics é a tipagem segura, além de você pode usar sem custo ou risco de conversões de tempo de execução ou operações boxing, como ocorre com o tipo object.

Usando classes genéricas

Calma, já disse que não é tão complicado quanto parece, simplificando, assim como nosso método pode receber o valor de uma variável por parâmetro, o tipo dessa variável também pode vir via parâmetro. ;)

Ex:

public void ShowMessage<T>(T obj) {
  Console.WriteLine (obj.ToString());
}

void Main() {
  ShowMessage<int>(3);
  ShowMessage<DateTime>(DateTime.Now);
  ShowMessage<string>("Rafael");
}

No exemplo temos um método chamado ShowMessage, que ira receber um parâmetro chamado obj, e o tipo desse parâmetro também ira ser informado por meio do T.

quando passamos o , ou apos o nome do método, estamos informando qual vai ser o valor do parâmetro.

A declaração também pode ser feita diretamente com a classe:

class Wallet<T>
{
  private List<T> MyItems;
  public DateTime Created { get; private set; }
  public DateTime LastUpdate { get; private set; }
  public T LastItem { get; private set; }

  public Wallet()
  {
    MyItems =  new List<T>();
    Created = DateTime.Now;
  }

  public void Add(T data)
  {
    MyItems.Add (data);	
    LastUpdate = DateTime.Now;
    LastItem = data;
  }
}

void Main()
{
  var stringWallet = new Wallet<string>();
  stringWallet.Add("teste 1");
  stringWallet.Add("teste 2");
  stringWallet.Add("teste 3");
	
  var intWallet = new Wallet<int>();
  intWallet.Add(1);
  intWallet.Add(2);
  intWallet.Add(3);	
}

No exemplo acima criamos uma classe chamada Wallet que ira armazenar uma lista de itens de qualquer tipo, como as operações executadas por ela são genéricas isso torna nossa vida muito mais fácil, em vez de criar uma wallet especifica para cada tipo que queremos armazenar podemos fazer isso uma única vez usando Generics.

Como podem ver o tipo T que informamos no momento que instanciámos a classe é utilizado de diversas maneiras, tanto para declarar o tipo de alguma variável, como tipo em parâmetros dos métodos e até mesmo como retorno da nossa função.

Por conversão costumamos usar a letra T como a variável que irá receber o tipo, mas podemos usar qualquer outro nome ou até mesmo receber mais de um tipo, como por exemplo:

public void ShowMessage<T1, T2>(T1 obj, T2 obj2) {
  Console.WriteLine (obj.ToString() + " " +  obj2.ToString());
}

void Main() {
  ShowMessage<string, int>("Rafael", 99);
}

Apesar de “genérico” o Generics pode seguir algumas regras para ajudar na codificação. Por exemplo podemos querer qualquer variável que implemente a interface IList somente;

public T Clear<T>(T obj) where T: IList {
  obj.Clear();
  return obj;	
}

Nesse caso o método só poderá receber como parâmetro alguma classe que implemente a interface IList, essa regra é feita utilizando o “where T: IList”.

Até a próxima.

Referências:

Delegates em C#

Delegate

Hoje vamos falar um pouco sobre Delegates, o próprio nome já passa uma ideia do seu propósito.

Delegates são formas de delegar funções para outros métodos, um delegate representa uma referencia para um método que pode ser passado via parâmetro.

Com isso abrimos um leque de possibilidades, como escolher o comportamento de uma funcionalidade em runtime, definir o callback para uma função e até mesmo extender o comportamento de alguma classe externa sem a necessidade de mudança direta no código original.

Delegates são semelhantes a ponteiros de função do C++, a referência da chamada de um método é enviada ou atribuída a um delegate em vez da função concreta, tornando assim os delegates ferramentas tão flexíveis no desenvolvimento de uma aplicação.

Um delegate é declarado utilizando a palavra reservada delegate como no exemplo a seguir:

public delegate string MeuDelegate(string nome);

Um delegate pode ser atribuído de diversas formas, utilizando um método nomeado, anonymous function ou até mesmo uma Lambda expression.

//Inicializando com um método já existente
MeuDelegate meuDelegate = FuncaoTeste; 

//Inicializando com uma anonymous function
MeuDelegate meuDelegate2 = delegate(string nome) { return $"Bem vindo {nome}!"; };

//Inicializando com uma Lambda expression
MeuDelegate meuDelegate3 = (nome) => ($"Bem vindo {nome}!");

Delegate ou MulticastDelegate?

Um delegate pode possuir retorno ou ser void, se um delegate não tiver nenhum retorno (void) ele automaticamente será do tipo System.MulticastDelegate, por conta disso, suportando o agrupamento com outras funções usando o operador “+=”

public delegate void Del(string message);

public static void DelegateMethod1(string message) => Console.WriteLine("DelegateMethod1 " + message);
public static void DelegateMethod2(string message) => Console.WriteLine("DelegateMethod2 " + message);
public static void DelegateMethod3(string message) => Console.WriteLine("DelegateMethod3 " + message);

void Main()
{
  Del d1 = DelegateMethod1;
  Del d2 = DelegateMethod2;
  Del d3 = DelegateMethod3;

  Del allMethodsDelegate = d1 + d2;
  allMethodsDelegate += d3;

  allMethodsDelegate("Rafael Orion"); //Os 3 métodos serão executados
}

Se o delegate tiver algum retorno, nesse caso ele será do tipo System.Delegate e não suporta agrupamento de métodos como o caso anterior.

Colocando a mão na massa!

Vamos montar um exemplo um pouco mais prático, imagine que temos uma função externa para fazer um processamento dos dados de uma lista, mas queremos a possibilidade de injetar alguns filtros quando necessário.

Aqui temos nossa classe do tipo Usuario:

public enum Sexo { Masculino, Feminino }

public class Usuario
{
  public int Id { get; set; }
  public string Nome { get; set; }
  public int Idade { get; set; }
  public Sexo Sexo { get; set; }
  public string Estado { get; set; }

  public Usuario(int id, string nome, int idade, Sexo sexo, string estado)
  {
    Id = id;
    Nome = nome;
    Idade = idade;
    Sexo = sexo;
    Estado = estado;
  }
  public override string ToString() => return $"Id:{Id} - {Nome}, {Sexo} ,{Idade} anos de {Estado}";
}

Aqui nosso delegate chamado “Filtro” que pode receber qualquer método com mesmos parâmetros e retorno:

public delegate List<Usuario> Filtro(List<Usuario> usuarios);

Aqui temos uma função que irá receber uma lista de Usuários, ordenar e exibir:

public void ExibirUsuariosOrdenados(List<Usuario> usuarios, Filtro filtros = null)
{
  //Efetua a ordenação
  var usuariosOrdenados = usuarios.OrderBy(_ => _.Nome).ToList();

  //Verifica se o delegate foi atribuído ou não
  if(filtros != null)
  {
    usuariosOrdenados = filtros(usuariosOrdenados); //Executa o delegate enviado
  }

  //Exibe o resultado no console da aplicação
  foreach(var usuario in usuariosOrdenados)
  {
    Console.WriteLine(usuario.ToString());
  }
}

Se chamarmos a nossa função ExibirUsuariosOrdenados sem passar nenhum delegate de filtro o resultado será somente nossa lista de nomes ordenada.

void Main()
{
  var usuarios = new List<Usuario>()
  {
    new Usuario(6,"Usuario 6", 18, Sexo.Feminino, "rio de janeiro"),
    new Usuario(4,"Usuario 4", 41, Sexo.Masculino, "minas gerais"),
    new Usuario(3,"Usuario 3", 12, Sexo.Masculino, "rio de janeiro"),
    new Usuario(8,"Usuario 8", 12, Sexo.Masculino, "sao paulo"),
    new Usuario(5,"Usuario 5", 34, Sexo.Feminino, "sao paulo"),
    new Usuario(7,"Usuario 7", 19, Sexo.Feminino, "sao paulo"),
    new Usuario(1,"Usuario 1", 15, Sexo.Masculino, "sao paulo"),
    new Usuario(9,"Usuario 9", 23, Sexo.Masculino, "rio de janeiro"),
    new Usuario(2,"Usuario 2", 29, Sexo.Feminino, "sao paulo"),
  };

  Console.WriteLine("Exibindo todos sem filtro");
  ExibirUsuariosOrdenados(usuarios);
}

nesse caso o resultado seria:

Exibindo todos sem filtro
Id:1 - Usuario 1, Masculino ,15 anos de sao paulo
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:3 - Usuario 3, Masculino ,12 anos de rio de janeiro
Id:4 - Usuario 4, Masculino ,41 anos de minas gerais
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:6 - Usuario 6, Feminino ,18 anos de rio de janeiro
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo
Id:8 - Usuario 8, Masculino ,12 anos de sao paulo
Id:9 - Usuario 9, Masculino ,23 anos de rio de janeiro

Criando um método para usar no delegate

public List<Usuario> FiltroMaioresDeIdade(List<Usuario> usuarios)
{
  return usuarios.Where(_ => _.Idade > 18).ToList();
}

Se passarmos o nosso método FiltroMaioresDeIdade para o delegate o resultado será:

Console.WriteLine("Exibindo com filtro de idade");
ExibirUsuariosOrdenados(usuarios, FiltroMaioresDeIdade);

Resultado:

Exibindo com filtro de idade
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:4 - Usuario 4, Masculino ,41 anos de minas gerais
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo
Id:9 - Usuario 9, Masculino ,23 anos de rio de janeiro

Também podemos definir atribuir um delegate usando lambda:

Console.WriteLine("Exibindo com filtro de cidade usando Lambda");
Filtro filtroPaulistas = (lista) => (lista.Where(_ => _.Estado.Equals("sao paulo")).ToList());
ExibirUsuariosOrdenados(usuarios, filtroPaulistas);

Resultado:

Exibindo com filtro de cidade usando Lambda
Id:1 - Usuario 1, Masculino ,15 anos de sao paulo
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo
Id:8 - Usuario 8, Masculino ,12 anos de sao paulo

Ok, mas posso executar mais de uma função ao mesmo tempo usando o mesmo delegate?

A resposta para essa pergunta é depende. Se o seu delegate tiver um retorno assim como no exemplo anterior não será possível encadear mais de uma função, isso só é possível para métodos void.

Então seguindo a lógica do nosso exemplo, se quisermos enviar mais de um filtro ao mesmo tempo temos que fazer algumas alterações:

Primeiramente nosso delegate não pode mais ter um retorno, para continuar alterando nossa lista sem um retorno vamos apelar para a mágica da passagem de parâmetro por referência, possibilitando que nosso método altere a lista original

public delegate void Filtro(ref List<Usuario> usuarios);

Os métodos dos filtros também precisam ser alterados:

public void FiltroMaioresDeIdade(ref List<Usuario> usuarios)
{
  usuarios = usuarios.Where(_ => _.Idade > 18).ToList();
}

public void FiltroPaulistas(ref List<Usuario> usuarios)
{
  usuarios = usuarios.Where(_ => _.Estado.Equals("sao paulo")).ToList();
}

Agora já podemos trabalhar com um ou mais filtros

  Console.WriteLine("Exibindo com filtro de idade");
  ExibirUsuariosOrdenados(usuarios, FiltroMaioresDeIdade);
  Console.WriteLine("\n");

  Console.WriteLine("Exibindo com filtro de cidade");
  ExibirUsuariosOrdenados(usuarios, FiltroPaulistas);
  Console.WriteLine("\n");

  Console.WriteLine("Exibindo com filtro de idade e cidade");
  Filtro multiplosFiltros = FiltroMaioresDeIdade;
  multiplosFiltros+= FiltroPaulistas; //Atribuindo um segundo método por meio do operador +
  ExibirUsuariosOrdenados(usuarios, multiplosFiltros);
  Console.WriteLine("\n");

Resultado:

Exibindo com filtro de idade
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:4 - Usuario 4, Masculino ,41 anos de minas gerais
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo
Id:9 - Usuario 9, Masculino ,23 anos de rio de janeiro

Exibindo com filtro de cidade
Id:1 - Usuario 1, Masculino ,15 anos de sao paulo
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo
Id:8 - Usuario 8, Masculino ,12 anos de sao paulo

Exibindo com filtro de idade e cidade
Id:2 - Usuario 2, Feminino ,29 anos de sao paulo
Id:5 - Usuario 5, Feminino ,34 anos de sao paulo
Id:7 - Usuario 7, Feminino ,19 anos de sao paulo

Como podem ver no exemplo é possível passar diversos métodos para o mesmo delegate, todos serão executados quando o delegate for executado.

Lembrando que esse problema apresentado poderia ser feito de diversas outras formas muito melhores, a ideia aqui é somente exemplificar o uso de um delegate de uma maneira simples, garanto que irá se deparar com diversas possibilidade no seu dia a dia. ;)

Referências:

Até a próxima.

.Net CLI

.Net CLI

Depois dessa pequena pausa, que tal voltar falando um pouco sobre o CLI do .NET

Junto com a vinda do .NET Core ganhamos de brinde o CLI (Command Line Interface), a nova ferramenta cross-platform que nos permite criar, compilar, publicar e manipular packages das nossas aplicações feitas com .net core.

Com o CLI fica mais fácil automatizar algumas tarefas de devops, desenvolver utilizando outros sistemas operacionais como Mac/Linux ou até mesmo migrar do VisualStudio para o VsCode ;)

Para utilizar os comandos do CLI basta ter o .Net Core instalado e usar o terminal de sua preferência.

A estrutura dos comandos segue o seguinte padrão:

 dotnet <command> <argument> <option>

Alguns exemplos:

  • Para criar uma nova aplicação Console chamada “NewConsole”
    dotnet new console -n NewConsole
    
  • para criar uma nova aplicação web mvc
    dotnet new mvc
    
  • Adiciona referência do Newtonsoft.json no projeto
    dotnet add package Newtonsoft.json
    

Alguns comandos básicos são:

  • dotnet new = Cria um novo projeto ou solution baseado em algum template específico
  • dotnet restore = Restaura as dependências do projeto
  • dotnet build = Compila a aplicação
  • dotnet Run = Executa a aplicação
  • dotnet publish = Efetuar o deploy da aplicação
  • dotnet test = Executa os testes unitários
  • dotnet vtest = Executa os testes unitários de um arquivo específico
  • dotnet pack = Gera um pacote do nuget com o código
  • dotnet clean = Limpa o output do projeto
  • dotnet sln = Modifica o .NET Core solution file.
  • dotnet add package = Adiciona a referência de um pacote do nuget no projeto
  • dotnet add reference = Adiciona referência de um outro projeto
  • dotnet remove package = Remove a referência de um pacote do nuget
  • dotnet remove reference = Remove a referência de um projeto
  • dotnet list reference = Lista todas as referências

Referências:

Até a próxima.

Domain Driven Design (DDD)

DDD

Comecei a ouvir falar de Domain Driven Design (ou DDD para os íntimos) na época em que entrei no grupo de discuções do DotNet Architects, percebi que tinha muita gente da comunidade falando a respeito e resolvi entender um pouco mais sobre esse tipo de arquitetura.

O DDD é um modelo de arquitetura proposto pelo Eric Evans apoiado por grandes gurus da informática, reúne muitos aspectos já existentes formando um padrão que é considerado por muitos como “o retorno da orientação a objeto”.

O foco do DDD é no Domínio (domínio é todo o universo que envolve o seu problema), através da utilização de uma Linguagem Ubliqua e um Modelo Rico, ele tenta prover uma arquitetura clara que revele com facilidade as características e funções de cada elemento do seu sistema assim como a interação entre eles.

Linguagem Ubliqua (ou linguagem onipresente) trata-se da padronização os termos usados na análise e no desenvolvimento, linguagem comum utilizando os mesmos termos do negocio no desenvolvimento evitando modificação dos mesmos ou abuso de termos técnicos não correspondentes ao negocio .

Modelo Rico basicamente seria o uso de objetos com propriedades e métodos, diferente do modelo anêmico onde os objetos possuem somente propriedades, e os métodos com a regra de negocio concentram-se em classes diferente.

Para criar um bom software você tem que conhecer bem o cenário, refletir o mundo real em código não é algo fácil, e a utilização de uma linguagem Ubliqua ajuda bastante na hora de construir essa ponte entre o mundo real e as classes. Todos os envolvidos devem estar falando a mesma língua, nada de “tecnês” que não faça parte do domínio.

DDD é ideal principalmente para domínios com regras de negócio complexas pois esse foco em separação de papeis, coesão e simplicidade ajuda e muito na hora de entender cada ponto do sistema para desenvolver e dar manutenção.

Este padrão arquitetural é constituído por alguns elementos, não é necessário utilizar todos, tudo depende do seu cenário; Alguns de seus elementos são: Serviços, Repositórios, Entidades, Objetos de Valor, Agregados, Factories, Modelo Rico,…

Brevemente vou descrever mais detalhadamente cada um de seus elementos.

Por mais que eu goste de DDD e acredite que é uma arquitetura muito poderosa não podemos dizer que ela veio para substituir as outras, um arquiteto de verdade deve saber observar o problema antes de tudo e decidir a melhor arquitetura que se encaixa ao cenário.

Gosto de trabalhar voltado a DDD de uma forma mais evolutiva, sem me prender logo de cara a todas suas recomendações, vou aplicando cada elemento conforme vai surgindo a necessidade.

E para quem quer se aprofundar no assunto recomendo a leitura do livro do Evans, também tem um e-book gratuito sobre o assunto no infoQ alem da palestra do Giovanni Bassi sobre DDD que dá uma boa ideia geral sobre o assunto.

Estrutura do DDD:

DDD

Até a próxima.

Acessando propriedades de uma master page através de uma content page

Quick Tip

Quick tip

Agora vou dar uma dica bem simples de como acessar propriedades que estão em uma master page por uma de suas paginas filho. Primeiramente vamos declarar uma propriedade publica na MasterPage:


Public String PropriedadePublica
{
       get { return (String)Session["PropriedadePublica"]; }
       set { Session["PropriedadePublica"] = value; }
}

Estou utilizando sessions para que os valores da propriedade não sejão perdidos a cada postback. Já na pagina filha para que possamos enchergar a propriedade da masterPage é preciso adicionar uma diretiva no aspx.

<% @MasterType VirtualPath="~/Site.master" %>

Lembrando que o caminho informado deve ser o mesmo que na propriedade MasterPageFile. Com isso já é possível acessar as propriedades de uma master page da seguinte forma:

lblTeste.Text = Master.PropriedadePublica;

Outra forma de acessar dados da Masterpage é atavéz de seus componentes; Para isso basta usar o comando FindControl como no exemplo:

var teste = ((Label)Master.FindControl("lblTeste")).Text

Até a próxima.

Tags: c#

Utilizando MSMQ (Microsoft Message Queue) no C#

MSMQ

O MSMQ (Microsoft Message Queue) é uma implementaçao da Microsoft presente desde o windows 95 para o enfileiramento de Mensagens.

As filas trabalham com a politica FIFO (First In First Out), ou seja, em uma fila podemos empilhar uma serie de mensagens, e sempre sera recuperado uma a uma começando pela ultima que foi inserida.

O MSMQ trabalha de forma assincrona, possibilitando que diferentes aplicaçoes comuniquem-se por meio de mensagens, o software envia as mensagens que serão empilhadas em uma fila gerenciada pelo proprio windows até que o programa receptor va até la pegar as mensagens.

Tipos de Filas

No MSMQ podemos criar filas Publicas ou Privadas. As filas publicas podem ser acessadas apartir de qualquer computador que faça parte do mesmo Dominio atravez do Active Directory, já as filas privadas são compartilhadas somente com os programas rodando na mesma maquina.

Transacional

Tambem podemos definir a fila como transacional ou não, protegendo a inserçao e remoçao de mensagens em casos de erros.

Instalando o MSMQ

Para começao a utilizar o MSMQ precisamos ir no “painel de controle” > “Programas e Recursos” > “Ativar ou desativar recursos do Windows” e marcar o checkbox “Serviços do MSMQ (Microsoft Message Queue)” como na imagem abaixo.

Quick tip

Mãos a Obra

Primeiramente é necessário adicionar a referencia para o “System.Messaging ” no projeto.

Como o MSMQ pode gerenciar varias filas quando formos criar/utilizar uma fila precisaremos dar um nome e caminho a ela.

Como no exemplo vou utilizar uma lista privada o caminho da lista deve ser “.\Private$\”, caso estivese criando uma lista Publica o caminho seria o o nome do dominio da Rede. O caminho deve ser passado junto com o nome da nossa lista.

Criando/Abrindo uma lista

MessageQueue msg;
var qName = @".\Private$\teste_app";
if (MessageQueue.Exists(qName))
    msg = new MessageQueue(qName);
else
    msg = MessageQueue.Create(qName);

Essa lista pode receber qualquer tipo de objeto, porem devemos escolher entre 2 tipos de formato, pode ser uma classe serializada ou binario. Lembrando que se optarmos pelo formato em binario tanto o programa que envia qnt o receptor deve fazer referencia para a mesma dll que contem o objeto.

No exemplo vou passar o seguinte objeto serializado.

[Serializable]
public class Job
{
    public int ID { get; set; }
    public String Nome { get; set; }
}

Vamos configurar o formato:

msg.Formatter = new XmlMessageFormatter(new Type[] { typeof(Job) });

Agora basta enviar o objeto para a fila

var obj = new CommomLib.Job(){ ID = 10 ,  Nome = "Processo 1" };
msg.Send(obj);

Para pegar um item da Lista a outra aplicaçao devera primeiramente abrir a lista da mesma forma utilizada anteriormente, em seguida utilizar o seguinte código:

var myMessage = msg.Receive();
Job myJob = (Job)myMessage.Body;

Pronto! simples, agora vamos parar de utilizar banco de dados para gerenciar filas ok 😉

Até a próxima. []s

Tags: MSMQ

Como adicionar confirmação de exclusão em um ActionLink

Quick Tip

Quick tip

Para adicionar uma confirmação de exclusão ou qualquer alerta em um ActionLink do asp.Net MVC é muito simples.



Segue um exemplo abaixo:

@Html.ActionLink(“Excluir”, “Delete”, new { id = item.Id }, new { @onClick =  “javascript:return ” + “confirm(‘Confirma a exclusão?’)”})

Em algumas sobrecargas o ActionLink recebe um Object para htmlAttributes, e é nele que colocamos o nosso javascript para o atributo onClick.

Lembrando que também podemos setar qualquer atributo html para o ActionLink dessa mesma forma.

Até a próxima.

Tags: c#

Utilizando Tipos Nulos em c# (Nullable Types)

Nulos

Em alguns casos precisamos trabalhar com tipos nulos, mas por padrão nem todos os tipos de variáveis aceitam, porem em c# é muito simples criarmos variáveis que possam assumir valores nulos.

Nullable Qualquer tipo pode passar a ser nullable , por exemplo uma variável do tipo int por padrão não pode receber null, para resolver isso basta adicionar o operador ? logo depois do tipo desejado. Declararmos da seguinte forma:

int? numero;
numero = null;

//ou

Nullable numero2;
numero2 = null;

Com isso criamos uma variável do tipo int nullable.

Utilizo bastante variáveis nullables por exemplo quando quero passar um parametro bool? ativo em uma funçao onde quando o valor for True trarei todos os registros ativos, False todos os Inativos e Null para trazer todos os ativos e inativos.

Operador ?? O operador ?? apesar de pouco conhecido é muito útil, com ele podemos verificar de forma rápida e elegante se uma variável possui valor nulo;

Exemplo:

int? numero = null;
int numero2 = numero??99;

string mensagem = null;
string mensagem2 = mensagem??"Mensagem Nula";

Com isso caso o valor da variável que antecede o operador ?? for nulo, será atribuido o valor que está posterior ao operador ??, caso contrario será atribuido o valor da variável em questão.

Ele trabalha de forma bem parecida a um if ternário:

int? numero = null;
int numero2 = numero == null ? 99 : numero;

Esse operador pode ser muito útil por exemplo em Getters para evitar retorno de um objeto não instanciado:

private IList empresas;
public IList Empresas
{
    get { return empresas = empresas ?? new List(); }
    set { empresas = value; }
}

Ou quando precisamos reistanciar algum objeto caso esteja nulo.

repositorio = repositorio ?? new Repositorio();
//Somente será reinstanciada caso sejá nulo.

Até a próxima.

[]s

Tags: c#

Consultando desempenho da maquina com o PerformanceCounter

Gerenciador de tarefas

Com o PerformanceCounter podemos obter diversas informações sobre o desempenho atual da maquina, como por exemplo quantidade de memória em uso, espaço livre no HD, processamento, etc.

Quando precisamos rodar um processo muito pesado em um servidor através de um serviço periódico muitas vezes vale a pena conferir a situação da maquina antes de iniciar o processo para evitar travamento do sistema. Ou ate mesmo utilizar essas informações para criar um monitorador dos recursos, vai da sua necessidade e criatividade.

Vamos para o que interessa.

Para pegar informações básicas sobre o uso de memória, hd e processador é muito simples, basta utilizar os seguintes comandos:

var cpu = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", "_Total");
var memory = new System.Diagnostics.PerformanceCounter("Memory", "% Committed Bytes In Use");
var hd = new System.Diagnostics.PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");

Console.WriteLine(" % Uso do Processador: {0}", cpu.NextValue());
Console.WriteLine(" % Uso de Memória: {0}", memory.NextValue());
Console.WriteLine(" % Acesso ao HD: {0}", hd.NextValue());

Para mais informações clique aqui

Até a próxima. []s

Debugando Windows Service

Debug

Hoje vou ensinar uma forma para debugar windows service.

Ao criarmos um projeto do tipo WindowsService não conseguimos debugar normalmente como qualquer outro tipo de projeto, porem temos uma forma bem simples para contornar esse problema.

Primeiramente devemos criar uma condição na classe Program.cs para identificar se o nosso projeto foi executado em modo de Debug para redirecionarmos a chamada.

Program.cs

  static void Main()
  {

      if (System.Diagnostics.Debugger.IsAttached)
      {
          MeuServico service = new MeuServico();
          service.StartDebug(new string[2]);
          System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

      }
      else
      {
          ServiceBase[] ServicesToRun;
          ServicesToRun = new ServiceBase[] { new MeuServico() };
          ServiceBase.Run(ServicesToRun);
      }
  }

Apos feito isso, basta editar a classe do nosso serviço e adicionar um método StartDebug como no exemplo abaixo.

No service:

   public void StartDebug(string[] args)
   {
       OnStart(args);
   }

Como o Método OnStarde é do tipo protected criamos esse novo método publico para redirecionar a chamada.

Pronto! já podemos debugar nosso projeto normalmente sem nenhum problema.

[]s

Como criar um actionLink para outra Area no Asp.Net MVC3

Quick Tip

Quick tip

Fala ae galera.

Quando comecei a trabalhar com áreas no asp.net MVC3 me deparei com essa situação de criar um link que aponte para uma área diferente. Apesar de ser algo simples fica a dica.

<%= Html.ActionLink(“Descrição do Link”, “NomeDaPagina”, new { area=”NomeDaArea”, controller=”NomeDoController” } )%>

Ou na sintaxe do Razor:

@Html.ActionLink(“Descrição do Link”, “NomeDaPagina”, new { area=”NomeDaArea”, controller=”NomeDoController” } )

Abraços,

Tags: asp.net mvc

Comandos do Nuget

Nuget

No post anterior falei um pouco sobre o NuGet, agora vou listar alguns dos principais comandos para você utilizar no console do Visual Studio.

Para exibir o shell de comandos do NuGet, vá no menu View/Other Windows/Package Manage Console.

A seguinte janela irá ficar visível:

nuget package manager

No combo do lado esquerdo selecionamos qual será nosso repositório, por padrão ele busca da web mas podemos informar um repositório privado.

No combo do lado direito selecionamos o projeto no qual as referencias serão aplicadas.

Pesquisando um pacote pelo NuGet:

Para pesquisar um pacote, por exemplo o NHibernate basta digitar o seguinte comando:

PM> Get-Package nhibernate -remote

Esse comando trará todos os pacotes que possuem “NHibernate” no nome.

O parametro “- remote” indica que o pacote será pesquisado no repositório selecionado em vez de buscar os pacotes instalados no projeto.

Adicionando referência de um pacote ao Projeto:

Para adicionar a referencia de um pacote, por exemplo o FluentNhibernate:

PM> Install-Package fluentnhibernate

Esse comando instalará o fluent e todas suas dependências, como por exemplo o NHibernate e Iesi.Collections, ele buscará sempre a versão mais atual.

Para não instalar as dependências basta adicionar o parâmetro “-ignoreDependencies”

PM> Install-Package fluentnhibernate -IgnoreDependencies

Também podemos informar qual versão desejamos instalar com o parâmetro -Version

Removendo um pacote do Projeto:

Para remover uma referencia basta usar o comando:

PM> Uninstall-Package FluentNHibernate

Atualizando um pacote adicionado:

Para atualizar um pacote para a versão mais recente: PM> Update-Package FluentNHibernate

Para atualizar um pacote para uma versão especifica: PM> Update-Package FluentNHibernate -version 1.0.0

Listando os pacotes Instalados:

Para listar os pacotes instalados a lógica é a mesma de quando buscamos no repositório, basta omitir o parâmetro “-remote”

Para listar todos instalados: PM> Get-Package

Para buscar algum especifico: PM> Get-Package nhibernate

nuget package manager

A documentação completa em inglês pode ser encontrada aqui.

Dica

O NuGet possui AutoComplete para auxiliar na digitação dos comandos e nomes de pacotes, basta pressionar a tecla Tab depois de digitar o inicio do comando.

Como zerar o valor de um campo Identity

Quick Tip

Quick tip

Fala ae Galera.

Vou postar uma dica simples mas útil. Ao Criarmos uma coluna identity no Sql Server, mesmo depois de apagar todos os dados da tabela, ao inserirmos um novo registro ele continuará incrementando o valor desse campo a partir do ultimo valor inserido. Para zerar esse contador basta executar o seguinte script:

DBCC CHECKIDENT( ‘ [NOME_DA_TABELA] ‘ , RESEED, 0)

ex: DBCC CHECKIDENT(‘Funcionarios’, RESEED, 0)

Também podemos modificar esse valor para que comece a partir de algum numero específico.

Ex: DBCC CHECKIDENT(‘Funcionarios’, RESEED, 50)

Nesse caso o Próximo registro inserido na tabela Funcionários assumira o valor 51.

Abraços,

Rafael Orion

Nuget

Nuget

NuGet é um projeto open source para gerenciar pacotes na plataforma .NET.

Com o NuGet as tarefas de adicionar uma biblioteca,configurar e atualizar ficaram muito mais fáceis. Basta buscar nele a biblioteca que deseja utilizar que fará o trabalho de configurar seu ambiente e instalar todas as dependências necessárias deixando tudo bem organizado e centralizado.

Por padrão o NuGet buscará as referências em um repositório publico na internet, mas você também pode montar um repositório local na sua empresa para suas bibliotecas, e apontar o nuget para buscar a partir dela.

Por exemplo, para adicionar o FluentNhibernate em nosso projeto da forma convencional precisaríamos seguir os seguintes passos:

  • Entrar no site do NHibernate e baixar a ultima versão.
  • Efetuar o download de todas as dlls dependentes, como por exemplo, o NHibernate.
  • Descompactar e copiar a dll para o nosso projeto.
  • Referenciar as dlls no projeto.
  • Em alguns casos efetuar alguma configuração no webconfig.
  • E torcer para não estar faltando nenhuma outra dependência.

Um pouco trabalhoso não acham? Mas como faríamos isso utilizando o NuGet?

No visual studio (com o plug-in do NuGet instalado) basta abrir o Console do NuGet e digitar a seguinte linha de comando:

Install-Package FluentNHinernate

Pronto! Já está funcionando!, Simples não é mesmo?

Ao executar esse comando, o NuGet vai até o seu repositório publico na internet e busca a versão mais recente do componente, todas suas dependências, efetua o download, joga em uma pasta chamada Packages dentro da sua solution e configura oque for necessário.

Também é possível especificar a versão do componente que será baixado, ignorar as dependências, remover pacotes, buscar por pacotes no repositório, atualizar referencias do projeto para uma versão mais recente, etc etc.

Para instalar o plug-in do NuGet, o projeto está hospedado no Github , lá você vai encontrar o código fonte, documentação, exemplos e o plug-in para o visual studio 2010.

A instalação não foge do padrão next, next , finish. E para visualizar o shell após a instalação vá no menu do VisualStudio View/Other Windows/Package Manager Console.

Depois farei um novo post demonstrando os principais comandos.

Abraços, Rafael Orion

Hello world!

Hello World

Finalmente, depois de algum tempo enrrolando, resolvi tomar vergonha na cara e criar um blog próprio (depois de algumas experiencias em um blog com o pessoal da faculdade).

O objetivo é compartilhar um pouco de conhecimento e dos meus estudos.

Let’s go!