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#

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

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