Compactando e Descompactando com SharpZipLib no .Net Framework

by Felipe Oriani 23. novembro 2011 12:45

Olá pessoal, hoje precisei realizar um processo com arquivos de texto do Open Office (com extensão .odt) que assim como as últimas versões do Microsoft Office, trabalha com arquivo de forma compactada e integrando todo o conteúdo dentro deste arquivo e interpretado pelo editor.  Neste arquivo vou demonstrar de forma rápida como compactar e descompactar arquivos na plataforma .Net utilizando o componente SharpZipLib

Você pode fazer o download do SharpZipLib neste link:

http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

A versão atual é a 0.86 e contém diversas possibilidades. Vou demonstrar aqui como compactar uma pasta e descompactar um arquivo .zip. Imaginando que você já possui um projeto e a DLL do SharpZipLib devidamente referenciada. 


Descompactar:

var zip = new FastZip();
zip.ExtractZip("C:\\input.zip", "C:\\temp", string.Empty);

Observe que o primeiro parâmetro é relacionado ao arquivo a ser extraído, o segundo é em qual diretório o conteúdo será exibido e o terceiro é um possível filtro para selecionar quais arquivos serão extraídos (passando uma string vazia indicamos que não temos filtro e todo o conteúdo será extraído).

Compactando uma pasta:

var zip = new FastZip();
zip.CreateZip("C:\\output.zip", "C:\\temp", true, string.Empty);

Neste segundo exemplo, informamos o qual o caminho do arquivo a ser gerado, o segundo parâmetro informa qual o diretório que desejamos compactar, o terceiro se o componente deve utilizar recursividade e por fim um filtro para arquivos a serem compactados.

Temos ainda a opção de compactar em um Stream (de memória, arquivo, rede etc), veja o exemplo:

var memory = new MemoryStream();
var zip = new FastZip();
zip.CreateZip(memory, "C:\\temp", true, string.Empty, string.Empty);

Neste exemplo, o primeiro parâmetro é um Stream (de memória neste caso), o segundo parâmetro a pasta que será compactada e os demais parâmetros assim como no primeiro exemplo de compactação.

Como meu caso tratava-se de um relatório, consegui dispensar a escrita em disco do resultado da compactação, modificando os arquivos necessários e entregando para o client o resultado direto da memória. 

Bem pessoal, é isso. Em um próximo artigo, pretendo mostrar como customizar arquivos .odt e .docx para geração de relatórios dinâmicos.

Obrigado!

Abraços!

Tags: ,

.Net Framework | C#

ASP.NET MVC - Quando utilizar ViewBag, ViewData e TempData ?

by Felipe Oriani 6. setembro 2011 05:17

Olá pessoal, neste post farei uma breve explicação de como trabalhar com mecanismos de transferência de dados no asp.net mvc, que existe uma certa semelhança entre eles mas existem recomendações de uso quanto ao cenário em que se aplica. Esta é uma questão que sempre vejo em alguns fóruns e listas de discussões, portanto resolvi escrever este post para entrar em um detalhe maior.

A ViewBag, ViewData e TempData são propriedades da classe base ControllerBase e ViewPage e basicamente são utilizados para transferir dados entre Controllers, Actions e Views.

ViewBag e ViewData

As propriedades ViewBag e ViewData, tem o mesmo objetivo, portar dados do Controller para uma View, porém a ViewData (do tipo ViewDataDictionary que implementa a interface IDirectionary<string, object>) é um dicionário de chaves/valores onde você determina uma chave string é possível aplicar um valor qualquer como object. A ViewBag é um wrapper para a ViewData, e esta por sua vez, utiliza recursos do .Net Framework 4.0 tendo pro definição seu  tipo como dynamic, o que nos permite criar propriedades em tempo de execução, fornecendo tipagem além de elegância. Ambas as propriedades são preenchidas em Actions (veja o método View da classe Controller do Asp.Net MVC http://aspnet.codeplex.com/SourceControl/changeset/view/68345#266451) e ficam disponíveis na View a ser renderizada e são recomendados para os cenários:

·         Preencher controles de seleção (combox, listbox, lista de checkboxes, lista de radiobuttons, etc..).

·         Transferir pequenos valores de dados (tipos primitivos).

·         Informações extras (exemplo: dados do usuário conectado a aplicação).

É importante destacar que devemos ter um cuidado maior quando utilizamos estas propriedades, pois se na View o código tentar acessar um valor não definido na ViewData ou ViewBag uma exceção será lançada na página. Quando utilizamos a ViewData, por estarmos utilizando um dicionário com uma chave em string e valor em object, é necessário realizar unboxing para o tipo correto do valor quando precisarmos acessar algo específico do objeto. Já com a ViewBag o unboxing torna-se desnecessário porém o mesmo cuidado quanto a existência de uma propriedade deve ser levado em consideração.

Um exemplo do uso da ViewData e ViewBag:

public ActionResult Index() {

   ViewData["Produto"] = "Guitarra";

   ViewBag.Cliente = "Felipe Oriani";

   return View();
}

Acessando estas informações na view:

Cliente: @ViewBag.Cliente

<br/><br />

Produto: @ViewData["Produto"]

<br/><br/>

Cliente (ViewData): @ViewData["Cliente"]

Como dito anteriormente, a ViewBag utiliza a ViewData para armazenar as propriedades, portanto as propriedades dinâmicas que são criadas na ViewBag tornam-se acessíveis na ViewData, mas recomenda-se o uso direto da ViewBag, uma vez que o projeto utilize a versão 3 do Asp.Net MVC.


TempData

Esta propriedade está presente também na classe ControllerBase e é do tipo TempDataDictionary (que implementa a interface IDirectionay<string, object) que trata-se de um dicionário de chave/valor. Seu uso é semelhante à ViewData, porém o objetivo principal da TempData são dados temporários que podem ser transportados para um novo contexto Http. Cenários recomendados:

·         Mover um objeto para outra action.

·         Manter algum estado quando um Redirect é realizado.

 

Vamos a um exemplo simples:

public ActionResult Direcionar()
{
   TempData["Tecnologia"] = "ASP.NET MVC"; 
   return RedirectToAction("Index");
}

Na view Index, conseguimos recuperar este valor, da mesma forma que fazemos com a ViewData, porém acessando a TempData.

TempData: @TempData["Tecnologia"]

Acessando diretamente a action Index, a TempData virá nula pois não foi setado. No caso de acessar a action Direcionar vocÊ será redirecionado para a index após ter criado uma chave na TempData, sendo assim, após o redirect do protocolo http para a action Index, um valor foi persistido no TempData (internamente em Session) o que permite o acesso desta chave no destino (lembrando que após a finalização da execução do Request, a TempData é liberada). Veja a imagem abaixo realizando um Debug ao tentar executar a Action 'Direcionar'.

 

Bem pessoal, por hoje é isso, algo simples e fácil de utilizar-se no asp.net mvc.

Um abraço

Tags: ,

ASP.Net MVC

Como começar os estudo em .Net Framework?

by Felipe Oriani 9. agosto 2011 05:07

Olá amigos, neste post vou listar aqui alguns dos itens de como começar a estudar o .Net Framework. Vejo esta questão freqüentemente em fóruns e listas de discussões, então resolvi escrever um post com links para um material de referência para começar os estudos com as ferramentas de desenvolvimento Microsoft, sem muitos gastos ou até mesmo sem.

Microsoft Visual Studio

Antes de começar a indicar referências, precisamos de um ambiente de desenvolvimento preparado para o estudo, portanto, nada melhor que uma IDE de qualidade. Hoje, temos o  Microsoft Visual Studio 2010, que possui uma versão gratuita, chamada Express. Você pode realizar o download neste link:

http://www.microsoft.com/express

Neste link, você encontrará as versões Express que são gratuitas do Visual Studio 2010 e Sql Server 2008. A versão Express do Visual Studio possui um software para cada plataforma ou seja, versão para Visual C#, Visual C++, Visual Web Developer, Visual Basic.Net, For Windows Phone e uma versão que inclui todos de forma integrada, All-In-One. Ao realizar o download, você pode instalar e terá uma IDE Microsoft preparada para o desenvolvimento com muitos dos recursos que a versão Professional possui. Caso você tenha recursos financeiros e está disponível em investir, vale a pena a compra da versão Professional do Visual Studio.

Livros e Downloads

http://www.novateceditora.com.br/livros/aspnet2/
Este é um livro do Alfredo Lotar que foca em desenvolvimento web com o Asp.Net. Quando estava iniciando, foi um livro que li e gostei. Como primeira leitura, acredito que vale a pena.

Se você tem bom conhecimento em inglês, sempre recomendo os livros da editora APress http://www.apress.com/microsoft/net-framework, que é a editora que a Microsoft trabalha e sempre contém excelentes materiais.

http://www.microsoft.com/download/en/details.aspx?id=23507
Este é um training kit disponibilizado e atualizado da Microsoft com o estudo focado em Visual Studio 2010 com .Net Framework 4.0.

 http://www.submarino.com.br/produto/1/203302/c
C# como Programar – é um livro extenso, em português com um bom conteúdo sobre C#. Eu li alguns trechos deste livro e gostei, mas acredito que seja um livro para consulta.

Websites e Portais

Com um ambiente preparado, vou deixar aqui alguns links de websites onde você poderá encontrar bons artigos:

http://msdn.microsoft.com/pt-br/
Portal da MSDN, com muito conteúdo oficial da Microsoft para começar os estudos, veja focado em ambiente web, desktop, mobile, etc... vale a pena estudar por aqui.

http://macoratti.net/
Excelente website sobre .Net em geral, ASP.Net, Windows forms e Visual Basic. Leitura fácil e rápida, sempre abordando assuntos atuais de forma rápida e objetiva.

http://www.codeproject.com/
Se você tem um bom conhecimento em inglês para leitura, este é um website com excelente artigos escrito por pessoas do mundo todo.

http://www.asp.net/
Website oficial do asp.net, possui muitos artigos, vídeos e tutoriais, sobre desenvolvimento web com o .Net Framework. Aborda o ASP.NET WebForms e ASP.NET MVC. Além de possuir alguns treinamentos em vídeos da plural signs, que na minha opinião são excelentes.

Fóruns e Lisas de discussões

http://stackoverflow.com/
Excelente fórum de discussão em inglês, em minha opinião um dos melhores. Utilizado por usuários do mundo inteiro, é focado em tecnologia/ferramentas de desenvolvimento de software em geral. Lembre-se de definir bem as tags de suas perguntas para ser melhor localizada por outros usuários.

http://www.dotnetbr.com/
https://groups.google.com/group/dotnet_br?hl=pt-BR
.Net BR é um grupo de discussão brasileiro muito ativo sobre .Net em geral.

http://www.dotnetarchitects.net/
http://groups.google.com/group/dotnetarchitects
.Net Architects é um grupo de discussão brasileiro sobre arquitetura de software com .Net. Excelentes profissionais estão presentes e sempre com boas discussões sobre o assunto. Aprendo muito nesta lista e sempre que posso compartilho algo.

http://social.msdn.microsoft.com/Forums/pt-br/categories/
Fórum oficial da Microsoft a respeito de suas tecnologias, existe categorias específicas para C#, VB.Net, Windows Forms, Asp.Net, Asp.Net MVC e Arquitetura de software.

Certificações

Se o seu objetivo é estudar para passar em uma prova de certificação, existem os livros da Microsoft que são chamados de Training Kits, pesquise o código da prova que qual tecnologia deseja realizar e procure na web, por exemplo: “Training Kit 70-515”, você encontrará  o livro preparatório específico para este exame.

Se você prefere um curso, pesquise uma instituição parceira da Microsoft que forneça os cursos oficiais e avalie a possibilidade. As escolas mais famosas são Ka Sollution, Green e  People. É um investimento.

Bem é isso pessoal, espero que tenham gostado e que ajude alguém que esteja no inicio da carreira e pretende investir tempo em conhecimento, o que é um excelente investimento.

Abraços

Tags: ,

Geral

ASP.NET MVC 3, IDependencyResolver com Microsoft Unity

by Felipe Oriani 21. julho 2011 11:29

Olá pessoal, dando continudade aos artigos sobre injeção de dependência (e inversão de controle), neste post pretendo mostrar de forma rápida como trabalhar com um container de dependências no ASP.NET MVC. Conforme os artigos anteriores, os exemplos utilizarão o Microsoft Unity.

Até a versão 2 no ASP.NET MVC, para resolver dependencias em nossos Controllers era necessário modificar a Controller Factory padrão (responsável por criar os controllers) do Asp.Net MVC herdando da classe DefaultControllerFactory e sobreescrevendo o método GetControllerInstance. Já na versão 3, este processo ficou mais fácil pois foi incorporada uma nova interface chamada IDependencyResolver que visa resolver dependencias de Controllers (onde podemos utilizar um container de dependencias para isto), veja sua declaração:

public interface IDependencyResolver {
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

Conhecendo esta interface, podemos realizar uma implementação básica junto a um container do Unity:

public class UnityDependencyResolver : IDependencyResolver
{
	private IUnityContainer container;

	public UnityDependencyResolver(IUnityContainer container)
	{
		this.container = container;
	}

	public object GetService(Type serviceType)
	{
		if (!container.IsRegistered(serviceType)) {
			if (serviceType.IsAbstract || serviceType.IsInterface) {
				return null;
			}
		}
		return container.Resolve(serviceType);
	}

	public IEnumerable<object> GetServices(Type serviceType)
	{
		return container.ResolveAll(serviceType);
	}
}

Uma vez tendo uma implementação desta interface e um container com todas as dependencias registradas, podemos seta-la como a “resolvedora” de dependencias em nosso projeto no arquivo global.asax no evento Application_Start, veja abaixo:

//declaração de nosso container de dependencias
private static UnityContainer _container;

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();
	
    // criando nosso container de dependencias e registrando uma dependencia de exemplo.
	_container = new UnityContainer();
	_container.RegisterType(typeof (IPersonRepository), typeof (PersonRepository));
	
	RegisterGlobalFilters(GlobalFilters.Filters);
	RegisterRoutes(RouteTable.Routes);
	
    //modificando o DependencyResolver para a nossa customização passando o container.
	DependencyResolver.SetResolver(new UnityDependencyResolver(this._container));
}

protected void Application_End() 
{
    // ao finalizar a aplicação, libera o container
    if (_container != null)
	    _container.Dispose();
}

No exemplo acima, criamos um container do unity e registramos um dependencia de um repositorio simples como exemplo. Na última linha, do método Application_Start, informamos ao DependencyResolver através do método SerResolver que nossa classe UnityDependencyResolver (implementação de IDependencyResolver) será nossa “resolvedora” de dependencias. Com isso, quando um controller necessitar de um dependencia (seja via construtor ou propriedade) ela será resolvida pela DependencyResolver.

Veja abaixo uma imagem do momento que um controller é instanciado e sua dependencia sendo resolvida com um repositório simples.

 IDependencyResolver com Microsoft Unity

Repare que o controller depende do tipo de uma interface que está registrada no container do unity e o tipo concreto que é instanciado é o respectivo ao registro no container.

Caso você queira dar uma olhada nos fontes do ASP.NET MVC 3, e ver como a controller factory utiliza uma instância de IDependencyResolver para trabalhar, clique aqui e entenda melhor como este processo funciona.

Espero que gostem e ajudem em seus projetos.

Abraços.

Tags: , ,

ASP.Net MVC | Padrões de Projetos

Como anunciar uma vaga de TI ?

by Felipe Oriani 12. julho 2011 10:43

 Olá pessoal, como estão!? Hoje não vou abordar nenhum assunto técnico.

É isso mesmo, neste artigo vou expor a minha opinião sobre como algumas empresas do setor de TI (no Brasil) vêm anunciando suas vagas. Desde já deixo claro quenão estou generalizando isso, e muito menos querendo aqui demonstrar um passo a passo de como fazer isso; simplesmente formei uma opinião sobre o assunto e tentarei aqui apontar algumas falhas que encontro em listas de discussões de tecnologias que participo, o que gera constrangimento de alguns integrantes quando uma vaga é mal anunciada.

Vou expor aqui algumas falhas que encontro constantemente, e apenas para enfatizar novamente, é minha opinião não generalizada. Muita coisa pode parecer obvias mas vou enfatiza-las.

Local de trabalho

Um dos problemas de anuncios de vagas em TI que sempre vejo é a falta de informação sobre o local de trabalho. É fato que algumas pessoas se esquecem de anunciar o local da vaga. Quando estou em busca de um emprego e me deparo com uma vaga assim, tento ver o website da empresa através da extenção do email do anunciante e assim descobrir onde esta empresa se localiza, tentando assim deduzir que a vaga é destinada a aquela cidade. Porém, muitas pessoas não pensam assim, e isso gera confusão.  Olhar o website da empresa não garante que aquele é o local da vaga, em algumas ocasiões esta vaga pode estar destinada para outra cidade onde o cliente desta empresa está alocado; portanto, sempre é bom enfatizar para qual cidade e região esta vaga está destinada.

Profissional “Deus”

Eu já perdi as contas de quantas vezes eu vi empresas anunciando vagas de TI com inúmeras especialidades, tudo bem, o setor é assim mesmo e geralmente um profissional pode ser especialista em várias tecnologias, mas o problema que vejo é quando precisam de um Deus para trabalhar, um exemplo do que eu já vi:

Analista/Programador Junior com experiência mínima de 4 anos em Delphi, ASP.Net, Windows Forms, WCF, C#, Sql Server, PHP, ASP, JSP, Ruby on Rails, Javascript, ActionScript, HTML, CSS, jQuery, ExtJs. Experiência em e-commerce e aplicações financeiras será um diferencial. O profissional atuará com em manutenções de aplicações existentes e suporte ao cliente.

Sugestão: Anunciem vagas objetivas, especialidades objetivas; diria que é quase impossível  encontrar um profissional que tenha quatro anos (ou mais) de experiência em muitas tecnologias assim e que aceite uma proposta Junior, portanto, mais senso em anunciar as vagas. Pessoas que aceitam vagas deste tipo, geralmente caminham para a uma futura frustração e optam por trocar de empresa num curto espaço de tempo, gerando rotatividade.

Pretensão Salarial

Acredito que são poucas as pessoas que gostam de ver quando uma vaga contém a seguinte frase “Enviar Curriculum Vitae com pretensão salarial”, por outro lado, todo profissional tem seu valor e o faz valer. Penso eu, que toda empresa sabe o quanto pode pretende investir em um determinado projeto, portanto faz-se justo que ela exponha esta informação no anuncio ou na primeira entrevista, ou pelo menos uma faixa salarial de acordo com a experiência. Penso que isso é questão de economia de tempo para ambas as partes; Conheço casos em que um profissional se dispôs a participar de um processo seletivo que durou cerca de três meses contendo 9 etapas e apenas no final, ele ter a surpresa de que o salário para aquela vaga, era 1/3 de seu salário atual.

Tecnologia existe a 5 anos e pede-se 8 anos de experiência.

Sim, isso é complicado mas ainda sim com uma baixa frequencia vejo vagas sendo anunciadas onde determinado tecnologia para a vaga tem X tempo de existencia e o requisito é X+Y tempo de experiência. Este tipo de falta de atenção gera uma visão errada da empresa anunciante pois o profissional ficará se questionando, “como uma empresa que sabe o que faz pode anunciar algo assim?”, portanto é sempre recomendável que o anuncio da vaga passe por um profissional técnico antes de ir para o mundo, para assim não gerar a imagem errada da empresa.

É constante ver problemas em vagas anunciadas, e muitas vezes quando encontro este tipo de anuncio (constantemente em listas de discussões), a empresa é taxada na thread da vaga, o que pode gerar uma imagem errada da empresa. As vezes a vaga pode ser ideal para alguém, porém por muitos integrantes estarem falando que aquilo é ‘furada’ ou ‘problemática’, outros profissionais podem deixar de enviar o seu curriculum e evitando assim uma possível contratação ideal para tal vaga. Existem muitos problemas neste assunto, mas não vou extender muito, basta olhar as listas de discussões que em poucos cliques você encontra uma thread cheia de comentários sobre vagas mal anunciadas.

Abraços
Att,

 

Tags:

Geral

Injeção de Dependência com Microsoft Unity (UnityContainer)

by Felipe Oriani 23. fevereiro 2011 05:45

 

Olá amigos! No post anterior, fiz uma breve introdução em um padrão chamado Injeção de Dependência, no qual gosto muito e utilizo em meus projetos. Neste post de hoje vou tentar demonstrar como utilizar um container para realizar a injeção de dependência de forma simples e prática. 

Existem várias bibliotecas que podem nos auxiliar com este processo, e particularmente tenho preferencial pela Microsoft Unity, pela facilidade que ela propõe. Existem outras como Ninject, Castle Windson, Spring.Net, entre outros.

Microsoft Unity

Inicialmente, o Unity fazia parte da Microsoft Enterprise Library, que até hoje é mantido pela Microsoft, que se trata de uma biblioteca de componentes (application block) que aplica as boas-práticas de desenvolvimento com .Net, práticas comuns do dia a dia como acesso a dados, validação, logging, entre outras. Com o Unity não foi diferente, passou a ser o bloco de injeção de dependência da Entreprise Library. Depois com o tempo, ele tornou-se independente e hoje estamos na versão 2.0. Você pode fazer o download do Microsoft Unity neste link.

http://www.microsoft.com/downloads/en/details.aspx?
FamilyId=2d24f179-e0a6-49d7-89c4-5b67d939f91b&displaylang=en

O Unity (assim como outras bibliotecas de injeção de dependência) fornece uma classe que tem como objetivo formar um Container de dependências, ou seja, em um container podemos registrar dependências que nosso software necessita e este por sua vez consegue construir objetos com estas dependências resolvidas.

Além da flexibilidade que ganhamos com a utilização de um container a produtividade aumenta, pois tudo no final parece ser um pouco mágico, bastando apenas solicitar um determinado tipo ao container que este nos retornara um objeto com suas dependências resolvidas e pronto para uso. Vamos a um exemplo prático.

Feito o download, instale o Unity em sua máquina de desenvolvimento e crie uma solução de testes no Visual Studio. Feito isso, adicione a referência do Unity (Microsoft.Pratices.Unity e Microsoft.Pratices.Unity.Interception.Configuration) como mostra na figura abaixo:

 

Figura 1: Adicionando referência para Microsoft Unity em projeto.
 

Feito isso, podemos começar a utilizar um container. Primeiramente vamos criar alguns exemplos para ilustrar o uso básico do container. A listagem abaixo, exibe um pequeno exemplo de uma interface para realizar log de aplicações e três simples implementações desta interface.

public interface ILogDeEvento
{
    void Escrever(string mensagem);
    void Escrever(string chave, string mensagem);
}

public class LogEvent : ILogDeEvento
{
    public LogEvent() { }

    private const string ChavePadrao = "MSUnitTest";
    public void Escrever(string mensagem)
    {
        Escrever(ChavePadrao, mensagem);
    }

    public void Escrever(string chave, string mensagem)
    {
        // cria-se a chave caso esta ainda não exista.
        if (!EventLog.SourceExists(chave))
        {
            EventLog.CreateEventSource(chave, "MSUnitTest");
        }

        //escreve no eventLog
        var myLog = new EventLog { Source = chave };
        myLog.WriteEntry(mensagem);
    }
}

public class LogXml : ILogDeEvento
{
    private const string Caminho = "LogXml.xml";

    public void Escrever(string mensagem)
    {
        using (var stream = new StreamWriter(Caminho))
        {
            var xml = new XmlSerializer(typeof(string));
            xml.Serialize(stream, mensagem);
        }
    }

    public void Escrever(string chave, string mensagem)
    {
        Escrever(mensagem);
    }
}


public class LogTxt : ILogDeEvento
{
    public LogTxt()
    {
    }

    private const string Caminho = "logDeEventos.log";
    public void Escrever(string mensagem)
    {
        using (var stream = new StreamWriter(Caminho, true))
        {
            stream.WriteLine(mensagem);
            stream.Flush();
        }
    }

    public void Escrever(string chave, string mensagem)
    {
        using (var stream = new StreamWriter(Caminho, true))
        {
            stream.WriteLine(string.Format("{0}: {1}", chave, mensagem));
            stream.Flush();
        }
    }
}

 

Listagem 1: Exemplo para implementação


Até aqui, nada de novo. Voltando ao projeto de testes, vamos adicionar um teste de unidade, a listagem abaixo demonstra como podemos utilizar o container da Microsoft Unity:

[TestClass]
public class UnityTest
{
    // declaramos um container...
    private IUnityContainer _container;

    public UnityTest()
    {
    }

    [TestInitialize()]
    public void UnityInit()
    {
        // realizamos a instância deste container...
        _container = new UnityContainer();

        // registramos uma dependência no container...
        _container.RegisterType(typeof (ILogDeEvento), typeof (LogTxt));
    }
        
    [TestCleanup()]
    public void UnityDispose()
    {
        // liberamos o container do heap..
        _container.Dispose();
    }
        
    [TestMethod]
    public void Deve_Resolver_Dependencia()
    {
        // obtendo um logger de eventos pelo container...
        var logger = _container.Resolve<ILogDeEvento>();

        // invocando um método da instância resolvida pelo container...
        logger.Escrever("Mensagem de erro para ser gerada em TXT.");
    }
}

Listagem 2: Implementação do Teste utilizando Unity Container.


Como podemos observar no código acima, no escopo da classe temos uma declaração de um objeto da interface IUnityContainer, que é a interface implementada pelo nosso container. No método UnitInit (que possui o atributo [TestInitialize]) realizamos a instância deste objeto e registramos uma possível dependência passando dois tipos, onde o primeiro tipo é o requisitado e o segundo o que será utilizado para resolver. Observe que o tipo requisitado foi colocado a Interface ILogDeEventos (o que é uma boa prática da orientação a objetos, uma vez que podemos utilizar instâncias que implementam tal interface em sua concretização) e o tipo que a resolve é uma implementação dela LogTXT. Escrevemos um método de testes simples, Deve_Resolver_Depencias e neste implementamos a resolução deste tipo registrado pelo  container, e se executarmos este teste, vemos nos resultados a saída do log em TXT. O mesmo vale se trocarmos o tipo de resolução para Xml ou EventLog.

Boas práticas com Injeção de Dependências.

Hoje em dia fala-se muito em realizar DI pelos construtores, propriedades ou métodos. Vou demonstrar aqui como realizar injeção de dependência pelo construtor, que na minha opinião é o tipo de dependência para um objeto que mais faz sentido, uma vez no construtor, sem tal dependência torna-se impossível construir o objeto.

Para ilustrar um exemplo disso, vamos criar uma classe que possui a implementação de um Logger, para um exemplo real, um Mock. A listagem abaixo exibe um pequeno exemplo abaixo:

public class Mock<T>
{
    private readonly ILogDeEvento _eventLog;
    public Mock(ILogDeEvento eventLog)
    {
        _eventLog = eventLog;
    }

    public void Salvar(T entidade)
    {
        // persistir objeto
        _eventLog.Escrever(string.Format("Objeto {0} salvo com sucesso. \n Valor: {1}", entidade.GetType().Name, entidade.ToString()));
    }
}

Listagem 3: Implementação de exemplo de Mock com dependência em construtor. 
 

Observe que além de um classe genérica, no construtor deste recebemos um objeto da interface ILogDeEventos e setamos em uma variável interna no escopo da classe. Pois bem, voltando a classe de testes, vamos criar um novo método para realizar um simples deste exemplo. Veja o código comentado abaixo:

[TestClass]
public class UnityTest
{
    // declaramos um container...
    private IUnityContainer _container;

    public UnityTest()
    {
    }

    [TestInitialize()]
    public void UnityInit()
    {
        // realizamos a instância deste container...
        _container = new UnityContainer();

        // registramos uma dependência no container...
        _container.RegisterType(typeof (ILogDeEvento), typeof (LogTxt));

        // registramos a dependência para o Mock genérico
        _container.RegisterType(typeof(Mock<>), typeof(Mock<>));

    }
        
    [TestCleanup()]
    public void UnityDispose()
    {
        // liberamos o container do heap..
        _container.Dispose();
    }
        
    [TestMethod]
    public void Deve_Resolver_Dependencia()
    {
        // obtendo um logger de eventos pelo container...
        var logger = _container.Resolve<ILogDeEvento>();

        // invocando um método da instância resolvida pelo container...
        logger.Escrever("Mensagem de erro para ser gerada em TXT.");
    }


    [TestMethod]
    public void Deve_Resolver_Dependencia_Em_Objeto()
    {
        // obtendo um Mock pelo container...
        var mock = _container.Resolve<Mock<string>>();

        // invocando um método da instância resolvida pelo container...
        mock.Salvar("Felipe Oriani");
    }
}

Listagem 4: Implementação do teste do uso do Mock junto ao Container de dependência.

A instância de um Mock tem o objeto de simular o comportamento de um objeto real de nossa aplicação e neste caso, estou utilizando este como um Repositório, que recebe em seu construtor um ILodDeEvento. Em nosso exemplo, estou registrando o Mock no container, pois este tem dependência (que devem ser resolvidas) e no método Deve_Resolver_Dependencia_Em_Objeto(), fiz um pequeno exemplo da crianção de um Repositório de Strings. Ao executar este teste, podemos olhar no output dos testes, que os logs são executados sem problemas, veja a imagem abaixo:

 

 

Figura 2: Resultado da saída do Log (em TXT).

 

Portando isso para uma aplicação do mundo real, se um dia resolvermos mudar nossa forma de realizar log da aplicação para XML ou EventLog, podemos simplesmente alterar a resolução para o container que funcionará sem problemas, uma vez que todas estas implementações de Log implementam a mesma interface, torna-se simples.

Bem pessoal o que gostaria de demonstrar neste post era isso.

Em um próximo post, pretendo abordar como utilizar o Unity no Asp.Net MVC para resolver dependências em Controllers e Repositórios de dados. Os exemplos utilizados neste post, estão no rodapé.

Vou deixar alguns links no final que utilizei como estudo e referência.

Espero que tenha gostado.

Abraços

Exemplo demonstrativo
MsUnityTests-Exemplo.zip (508,09 kb)

Links e Referências

http://en.wikipedia.org/wiki/Dependency_injection

http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

http://viniciusquaiato.com/blog/injecao-de-dependencia-com-ms-unity/

http://goo.gl/OKJIx

Tags: ,

C# | Padrões de Projetos

Injeção de Dependência (Dependency Injection)

by Felipe Oriani 8. fevereiro 2011 06:01

 

Desde que comecei meus estudos com arquitetura de software passei a prezar mais pela qualidade do código e a facilidade de trabalhar com boas práticas.  Existe um padrão chamado Injeção de Dependência no qual será assunto deste breve post. O que é e para que serve? Como utilizá-lo? São questões que tentarei abordar durante o post.

O que é Injeção de Dependência e para que serve?

Segundo a Wikipédia, Injeção de Dependência é um padrão de desenvolvimento de software utilizado quando necessitamos manter um baixo acoplamento entre as camadas (módulos) de um sistema. Mas o que seria este acoplamento? O acoplamento dá-se a partir do momento em que você gera uma nova instância direta de uma classe que pertence a outro módulo em um segundo módulo, ou seja, este passa a depender diretamente daquele tipo e não de uma abstração. Um exemplo simplista disso:

 

public class CompraService {
   public void PagarCompra(Compra compra) {
       var repositorio = new RepositorioDeCompra();
       repositorio.PagarCompra(compra);
   }
}

 

Neste exemplo, a partir do momento que definimos uma instância do RepositorioDeCompra()  (linha 3) em nosso serviço, estamos acoplando diretamente nosso repositório ao serviço. Ou seja, ele depende diretamente da referência da classe RepositorioDeCompra. Isso funciona perfeitamente, mas poderíamos melhorar um pouco a fim de desacoplar nosso serviço.

Mas como podemos melhorar isso?

É possível realizar uma abstração utilizando uma interface, ou seja, depender de uma implementação de uma interface ao invés de uma classe concreta. Com isso temos a vantagem de mudar a instância no momento em que necessitarmos um exemplo:

 

public class CompraService {

   protected IRepositorioDeCompra Repositorio {
       get;
       private set;
   }

   public CompraService(IRepositorioDeCompra repositorio) {
      this.Repositorio = repositorio;
   }
   public void PagarCompra(Compra compra) {
      this.Repositorio.PagarCompra(compra);
   }
}


Podemos ver que no exemplo, utilizamos uma abstração do RepositorioDeCompra, ou seja, uma interface que contém assinaturas de métodos que devem ser implementados pela instância a ser passada no construtor do serviço (que deixa explícito o requisito; podemos trabalhar com dependência em propriedades ou parâmetro em métodos; em tempo vamos  entender o conceito em construtores). Isso nos da uma flexibilidade maior, pois podemos passar qualquer objeto de uma classe que implemente esta interface, mantendo o baixo acoplamento entre a camada de serviço e sua intermediaria. E para finalizar um exemplo desta interface e suas implementações:

 

interface IRepositorioDeCompra {
    void Salvar(Compra compra);
    void Excluir(Compra compra);
    IEnumerable<Compra> ObterTodos();
    Compra Obter(int id);
    void PagarCompra(Compra compra);
    void ReceberCompra(Compra compra);
    void CancelarCompra(Compra compra);   
}

public class RepositorioDeCompra : IRepositorioDeCompra { ... }
public class RepositorioDeCompraNHibernate : IRepositorioDeCompra { ... }
public class RepositorioDeCompraEF : IRepositorioDeCompra { ... }
public class RepositorioDeCompraAdo : IRepositorioDeCompra { ... }
public class RepositorioDeCompraXml : IRepositorioDeCompra { ... }

 


Com isso, podemos passar qualquer uma dessas instâncias, pois estas implementam IRepositorioDeCompra.  Na prática isso poderia ser utilizado da seguinte forma:

 

var servico = new CompraService(new RepositorioDeCompraNHibernate());
var servico = new CompraService(new RepositorioDeCompraEF());
var servico = new CompraService(new RepositorioDeCompraAdo());

 

Apesar de ser simples o assunto, recomendo que utilizem um container de dependências, que será assunto para um próximo post.

Espero que tenham gostado e entendido.

Um abraço!

 

Referências:
http://en.wikipedia.org/wiki/Dependency_injection
http://viniciusquaiato.com/blog/injecao-de-dependencia/

Tags: ,

C# | Padrões de Projetos

ASP.NET MVC 3 e HTML

by Felipe Oriani 5. janeiro 2011 04:34

Olá amigos, neste post de hoje vou deixar dicas simples mas útil que veio complementar o asp.net mvc 3. Pelo fato de o asp.net mvc 3 ainda estar na versão RC2, podem haver mudanças em sua versão final. O pequeno artigo de hoje, trata-se de métodos e atributos para se trabalhar com HTML.

O Método Html.Raw

Este é um novo método de extenção na classe HtmlHelper com a assinatura IHtmlHelper.Raw(string value) que tem o intuito de exibir um conteúdo em HTML de forma segura, ou seja, uma string com conteúdo formatado em HTML. O método é útil pois quando utilizamos a Razor View Engine, por padrão o Response já imprime o conteúdo de strings em unencoded, então o método nos ajuda a enviar conteúdo Html para ser interepretado ao browser através de código server-side dinâmico. Veja um exemplo de uso:

 

@{ 
   var texto = "<p>Este é um texto para ser exibido em <strong>HTML</strong> puro.</p>";
}

Conteúdo da váriavel: 
@texto

<br><br>

Conteúdo da váriavel (Raw):
@Html.Raw(texto)

 

O output disso, seria desta forma:

 

Conteúdo da váriavel:  &lt;p&gt;Este &#233; um texto para ser exibido em &lt;strong&gt;HTML&lt;/strong&gt; puro.&lt;/p&gt;

<br><br>

Conteúdo da váriavel (Raw): <p>Este é um texto para ser exibido em <strong>HTML</strong> puro.</p>

 

Ou seja, o método gera o Html da forma correta, enquanto a primeira abordagem transforma o conteúdo da string em HTML seguro.

O Atributo AllowHtml

Outros recurso interessante e simples que será introduzido no Asp.Net MVC 3, é a possibilidade de deixar de forma explícita que uma propriedade de nosso model permite conteúdo em formato Html. Esta possibilidade da-se pelo atributo AllowHtmlAttribute. Um exemplo simplista disso:

 

using System.Web.Mvc;

public class Produto {
   //outras propriedades
   [AllowHtml]
   public string Detalhes { get; set; }
}

 

Tendo isso em mente, quando formos efetuar um bind deste model, o asp.net mvc já saberá que aquela propriedade pode possuir contéudo em html e irá desabilitar o "HTML injection protection" que efetua uma validação contra post de conteúdo html para o servidor.

Bem, era isso o que gostaria de passar hoje, espero que seja útil a alguem.

Abraços

Referência: http://www.asp.net/learn/whitepapers/mvc3-release-notes#0.1__Toc274034209

Tags: ,

ASP.Net MVC

ViewModel Dynamic em ASP.Net MVC 3

by Felipe Oriani 9. setembro 2010 05:42

Olá amigos, neste post vou abordar um novo recurso que estará disponível no Asp.Net MVC 3 (atualmente no Preview 1) que é a possibilidade de termos propriedades dinâmicas no ViewData (ViewModel no Asp.Net MVC 3). Antes de abordar o tema principal do post, vamos entender como o ViewData trabalhou trabalha no Asp.Net MVC.

Todo controller em ASP.Net MVC deve herdar diretamente (por default) ou indiretamente de uma classe base chamada “Controller” que está debaixo de System.Web.Mvc para que o framework consiga entender que tal classe é um Controller. Como todos sabem, controllers possuem métodos que podem ser chamados de “Actions” que definem o tipo e qual View será renderizada, e em alguns momentos desejamos passar alguma informação para esta View. Para isso, uma propriedade publica na classe Controller chamada ViewData é responsável por enviar informações para que possam ser acessadas na View.

Esta propriedade ViewData que é do tipo  IDictionary<string, object> (classe concreta ViewDataDictionary) é um objeto do que através de uma chave (string) retorna qualquer objeto (object). Por um lado, isto facilitou muito a vida dos desenvolvedores pois podemos passar qualquer informação para a View sendo que o tipo Object é o tipo básico pra qualquer objeto em .Net. Por outro lado gerou conflitos, pois além de não ser type safe (ou tipado, ter a garantia que aquela instância é de determinado tipo, havendo a necessidade de realizar uma conversão), alguns erros podem passar despercebidos como os índices podem ser “strings mágicas”.

Com isso, foi implementado uma nova propriedade chamada ViewModel na classe controller, que é do tipo dynamic (novo recurso disponível a partir do .Net Framework 4.0) que permite que você defina propriedades em tempo de execução e o compilador as resolve para nós definindo o tipo, ou seja, quando fazíamos:

 

ViewData["Mensagem"] = "Olá Mundo ViewData";

 

Agora podemos fazer:

 

ViewModel.Mensagem = "Olá Mundo ViewData";

 

Perceba que ViewModel é outra propriedade, ou seja, ViewData ainda existe porém não contém recursos de type safe, já a ViewModel pelo fato de ser do tipo dynamic, conseguimos definir uma propriedade qualquer e aplicar um valor, como neste exemplo onde definimos uma propriedade chamada “Mensagem” e aplicamos a string  “Olá Mundo ViewModel” fazendo com que dinamicamente o .Net Framework identifique e a crie para nós tal propriedade de tal tipo; Na View conseguimos recuperar ambos os valores tanto como ViewData como ViewModel.

A vantagem disso é que agora temos uma propriedade específica para aplicar ViewModel (boa prática comum até a versão 2.0 do Asp.Net MVC). Podemos utilizar o ViewModel com propriedades dinâmicas a fim de ter maior segurança que tal tipo será retornado durante o processo de execução. Para ilustrar vamos a um exemplo.

Imagine que em nosso projeto temos uma página que irá listar os produtos de um catálogo. Para tanto precisaremos de uma classe produto em nosso Modelo, que defini da seguinte forma:

public class Produto
{
   public string Nome { get; set; }
   public decimal Valor { get; set; }
 
   public Produto(string nome, decimal valor)
   {
      this.Nome = nome;
      this.Valor = valor;
   }
}

Em seguida desejamos listar produtos em nossa página, então poderíamos fazer algo do tipo em uma Action:

 

public ActionResult Index()
{
   ViewModel.Titulo = "Produtos do Catálogo"; 
   ViewModel.Produtos = ObterProdutos();
 
   return View();
}

 

No código acima, definimos uma propriedades chamada Produtos que é inicializada a partir de um método chamado ObterProdutos() que retorna um IEnumerable<Produto>. Em nossa View, conseguimos recuperar a propriedade Produtos e iterá-la pelos objetos:

 

<h2><%: View.Titulo %></h2>
   
<% foreach (var produto in View.Produtos) { %>
   <%: produto.Nome %> - <strong><%: produto.Valor.ToString("C2") %></strong><br />
<% }%>

 

O resultado:

  

 

Bem, era isso que gostaria de mostrar.

Em minha opinião este recurso irá facilitar muito, pois não vejo mais a necessidade de ficar criando ViewModel para cada View.

Espero que gostem!
Abraços

 

Referências:
http://haacked.com/archive/2010/08/02/dynamic-methods-in-view-data.aspx
http://www.asp.net/mvc

Download do exemplo: Mvc3Dynamic.zip (319,37 kb)

Tags: , , ,

ASP.Net MVC

Upload de Arquivos com Asp.Net MVC

by Felipe Oriani 8. setembro 2010 04:32

 

Olá amigos, neste post vou falar um pouco de como trabalhar com arquivos em Asp.Net MVC ou seja, fazer upload. Vou tentar ser direto e prático.

Vamos ao Visual Studio (2008 ou 2010) e crie uma nova aplicação Asp.Net MVC 2 , e vamos ao código de nosso controller Home e crie uma action (métodos) chamada Upload, para receber como no código abaixo:

public ActionResult Upload()
{
   return View();
}

Se você possui algum conhecimento em Asp.Net MVC, você deve saber que este framework trabalha sobre um sistema de rotas, que toma como base Actions de um Controller. Tendo isso em mente, podemos criar uma view na pasta Views/Home chamada Upload (arquivo Upload.aspx), que será a renderização[3] padrão desta Action. Ao criar esta View, adicione o código abaixo:

<h2>Upload de Arquivo</h2> 
    <% using (Html.BeginForm("Upload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" })) { %>
        <input type="file" id="arquivo" name="arquivo" />
        <input type="submit" value="Upload" />
    <% } %>

O código acima renderiza um formulário simples para upload de arquivo, dizendo que a tag <form /> será submetida a um action chamada Upload no controller Home pelo método Post junto ao atributo enctype que especifica o tipo de conteúdo que será enviado neste formulário.

Você deve estar se perguntando, como que este formulário irá submeter informações para a mesma action que a renderizou ? De fato, pode parecer mas não é devido a sobrecarga de métodos que podemos fazer .Net. Em nosso controller Home, vamos adicionar outro método que irá receber este arquivo, porém com algumas diferenças, veja no código abaixo:

[HttpPost]
public ActionResult Upload(HttpPostedFileBase arquivo)
{
     if (arquivo != null)
     {
          arquivo.SaveAs(Server.MapPath("~/arquivos/") + Path.GetFileName(arquivo.FileName));
          return RedirectToAction("Index");
     }
     return View();
 }

Repare que este método possui uma assinatura diferente do anterior (aplicando a sobrecarga de métodos). O método possui um atributo chamado HttpPost, que implica que aquela Action pode ser invocada a partir do método Post, além de receber também a instância de um objeto HttpPostedFileBase que é o objeto correspondente para nosso arquivo no formulário. 

Com isso testando se algum arquivo foi realmente postado (verificando se o objeto não é nulo) e salvamos este em algum local (estou salvando em uma pasta chamada “arquivos” em projeto, em seguida redirecionamos o usuário para a view Index, do contrário a view de Upload é renderizada novamente. 

Obs: Não estamos fazendo algum tipo de validação mas isso seria possível através de algumas propriedades que o objeto arquivo (de HttpPostedFileBase) disponibiliza. 

Bem, de maneira simples vimos como podemos fazer upload em Asp.Net MVC, e com isso temos várias possibilidades como por exemplo, validar upload de determinados tipos de arquivo, arquivos compactados, imagens a serem trabalhadas, entre outros.

 

Espero que ajude alguém
Abraços

Referências:
http://cavalcante.net/
http://www.asp.net/mvc

 

 

 

MvcUpload.zip (300,73 kb)

Tags: , ,

ASP.Net MVC | C#

Sobre

Sou Felipe Oriani e trabalho com desenvolvimento web desde 2004, com tecnologias Microsoft como Asp e Asp.Net utilizando as linguagens C# e Vb.Net. Bacharel em Ciência da Computação pela Escola de Engenharia de Piracicaba,  MCTS (.Net Framework 3.5, ASP.NET Applications). Conheça um pouco mais sobre meu CurrículumVeja mais 

Social

profile for Felipe at Stack Overflow, Q&A for professional and enthusiast programmers

Selos

MCTS .Net Framework 3.5, ASP.NET Developer

MCP - Microsoft Certified Professional