Arquivo para a categoria ‘Enterprise Library’

Inversão de controle com Unity

Sexta-feira, 18 de julho de 2008 por carlos.mendonca

No último post iniciamos nossa breve visita ao “Enterprise Library 4.0” com o “Cryptography Application Block”. Neste post vamos analisar o “Unity Application Block” que é uma novidade na versão 4 da biblioteca. O “Unity” é um container de inversão de controle baseado na biblioteca “ObjectBuilder2” do “Entreprise Library” e que foi lançado como uma alternativa às já tradicionais bibliotecas “Spring.NET” (uma versão da famosa biblioteca Spring do mundo Java), “Castle Windsor”, “StructureMap”, “ObjectBuilder” etc.

Quem já utilizava o “Enterprise Library” em alguma de suas versões anteriores deve estar familiarizado com a biblioteca “ObjectBuilder”. Ela atuava no núcleo do “Enterprise Library” cuidando do gerenciamento dos objetos e apesar de não ser um “cidadão de primeira classe” (já que não era promovido como um dos conjuntos de aplicação), podia ser referenciado e utilizado diretamente pelo usuário. Muitos reclamavam de questões relativas ao design e performance da biblioteca e, a partir do feedback dos usuários e observação dos projetos da comunidade, a Microsoft refez o código e lançou o “ObjectBuilder2”. Baseado nele, foi construído o “Unity Application Block” e a novidade é que apesar de fazer parte do “Enterprise Library”, pode ser baixado separadamente através do portal CodePlex.

Conforme mencionei, o “Unity” é apenas uma alternativa a outras bibliotecas. Dito isto, podemos esperar muitas funcionalidades parecidas, algumas inéditas e algumas que faltam. A intenção deste post não é fazer uma comparação entre todas as bibliotecas disponíveis, mas visitar algumas das funcionalidades básicas do “Unity” para que seja mais fácil explorar daí pra frente.

Usando o “Unity Application Block”

Após baixar e instalar o pacote do CodePlex, vamos criar um novo ConsoleApplication no Visual Studio 2008 e referenciar as duas bibliotecas principais do “Unity” que já estão registradas no GAC da máquina: Microsoft.Practices.Unity, Microsoft.Practices.Unity.Configuration e Microsoft.Practices.Unity.ObjectBuilder2.

Para iniciarmos com um exemplo, vamos imaginar uma aplicação simples onde queremos criar um log. Podemos ter várias implementações deste “logger”, por exemplo, uma que escreve as mensagens direto no console e outra que escreve em um arquivo texto. Se fizermos com que estes dois “loggers” implementem uma interface comum, ganhamos flexibilidade por podermos especificar através de um arquivo de configuração qual gostaríamos de usar.

Esta seria a interface em questão:

public interface ILogger
{
    void Log(string message);
}

Há apenas um método que recebe a mensagem que gostaríamos de escrever. Para ela, criamos duas implementações:

public class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}
public class TextFileLogger : ILogger
{
    public void Log(string message)
    {
        using (StreamWriter streamWriter =
new StreamWriter("log.txt", true))
        {
            streamWriter.WriteLine(message);
        }
    }
}

Se utilizarmos apenas a interface ILogger, já podemos escrever o comportamento da nossa prova de conceito:

ILogger logger;
logger.Log("Aplicação foi iniciada.");
logger.Log("Aplicação foi finalizada.");

Falta apenas inicializar o objeto logger. Para isso, utilizaremos as classes do namespace Microsoft.Practices.Unity, de forma que o método Main fica assim:

static void Main(string[] args)
{
    UnityContainer unityContainer = new UnityContainer();
    unityContainer.RegisterType(typeof (ILogger),
typeof (ConsoleLogger));
    ILogger logger = unityContainer.Resolve<ILogger>();
    logger.Log("A aplicação foi iniciada.");
    Console.ReadLine();
    logger.Log("A aplicação foi finalizada.");
}

Vamos analisar passo-a-passo o que fizemos: em primeiro lugar, inicializamos o objeto unityContainer com o construtor padrão. Depois, configuramos programaticamete o Unity através do método RegisterType. Neste caso, criamos a associação dizendo que a interface ILogger deve ser associada à implementação ConsoleLogger. Ao rodar o programa, podemos ver que as mensagens são impressas na tela. Seriam impressas no arquivo log.txt se a associação da interface ILogger fosse com a implementação TextFileLogger.

A princípio, a menos que a intenção seja aproveitar o controle do ciclo de vida dos objetos que o Unity fornece (para encapsular nossa implemenação em um singleton, ou pedir uma instância por chamada), não há muito sentido em configurá-lo programaticamente. O código equivalente a este, mas com as configurações no App.config seria o seguinte:

static void Main(string[] args)
{
    UnityContainer unityContainer = new UnityContainer();

    UnityConfigurationSection unityConfigurationSection =
(UnityConfigurationSection) ConfigurationManager.GetSection("unity");
unityConfigurationSection.Containers.Default.Configure(unityContainer);
    ILogger logger = unityContainer.Resolve<ILogger>();
    logger.Log("A aplicação foi iniciada.");
    Console.ReadLine();
    logger.Log("A aplicação foi finalizada.");
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type=
"Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <typeAliases>
      <typeAlias alias="ILogger"
type="ConsoleApplication1.ILogger, ConsoleApplication1" />
      <typeAlias alias="ConsoleLogger"
type="ConsoleApplication1.ConsoleLogger, ConsoleApplication1" />
      <typeAlias alias="TextFileLogger"
type="ConsoleApplication1.TextFileLogger, ConsoleApplication1" />
    </typeAliases>
    <containers>
      <container>
        <types>
          <type type="ILogger" mapTo="ConsoleLogger" />
        </types>
      </container>
    </containers>
  </unity>
</configuration>

Com este exemplo iniciamos a utilização do Unity, mas ainda há muitos recursos a explorar. Na seção de links, ao final do post, há uma lista de blogs que possuem exemplos de aplicação que estendem o que já fizemos. Uma modificação imediata que poderíamos fazer seria especificar o nome do arquivo log.txt através do próprio arquivo App.config, bastando apenas passá-lo através de um construtor da classe ConsoleLogger.

.NET Enterprise Library – Logging

Sexta-feira, 27 de junho de 2008 por Flavio Mori

Uma boa solução de log para a plataforma .NET é o Logging Application Block, que pertence à Enterprise Library, já citada nesse blog.

Além dessa biblioteca facilitar o uso de log, ela gera saídas que podem ser direcionada para vários destinos. Algumas das possibilidades são:

  • O log de eventos do Windows
  • Uma mensagem de e-mail
  • Um banco de dados
  • Uma fila de mensagem
  • Um arquivo texto
  • Um evento WMI

Para o código a maneira como a informação será logada fica transparente já que isso é configurado no App.config ou Web.config.

Os principais elementos configurados são: Formatters, que definem o formato do texto a ser logado; Trace Listeners, que definem o destino do log; e Category Sources, que permitem classificar os Trace Listeners em categorias.

Vamos fazer um tutorial para vermos algumas funcionalidades básicas. Queremos logar informações a respeito de erros em processos em dois lugares: um arquivo texto e no log de eventos do Windows. Vamos criar uma categoria para os logs de erro nos processos chamada “Erro”. Essa categoria vai possuir dois Trace Listeners, um para um arquivo de log e outro para o log de eventos do Windows.

  • No Visual Studio, crie um novo projeto do tipo Console Application.
  • No projeto, adicione um novo item do tipo Application Configuration File (cujo nome padrão é App.config).
  • No Solution Explorer clique com o botão direito no App.config e selecione Edit Enterprise Library Configuration.

Edit Enterprise Library Configuration

  • Na tela que abriu, clique com o botão direito no nó correspondente ao App.config e selecione New > Logging Application Block para criar um novo nível na árvore chamado Logging Application Block.

New Logging Application Block

  • Clique com o botão direito em Formatters e escolha New > Text Formatter.
  • Na janela Properties mude o nome para “FormatterTeste” e clique no botão “…” do Template. No Template Editor, mude o texto para “{timestamp} {severity} – Erro no processo {processName}”. Agora temos um Formatter que irá gerar mensagens do tipo “28/6/2008 00:13:21 Error – Erro no processo ProcessoTeste”.
  • Clique com o botão direito em Trace Listeners e vá em New > Flat File Trace Listener. Na janela Properties selecione o Formatter “FormatterTeste”. Delete o conteúdo de Footer e Header, pois não queremos rodapé nem cabeçalho no arquivo de log. Em Filename, defina o local e o nome do arquivo (por exemplo c:\teste.log).
  • Crie um Trace Listener do tipo Formatted EventLog Trace Listener. Na janela Properties mude o seu Formatter para FormatterTeste.
  • Em Category Sources clique com o botão direito e vá em New > Category e renomeie-a para “Erro”.
  • Clique com o botão direito na categoria “Erro” e vá em New > Trace Listener Reference. Altere ReferencedTraceListener para FlatFile TraceListener.
  • Repita o último passo para o Formatted EventLog TraceListener criado por você.
  • Salve o arquivo App.config que você está editando.

No Solution Explorer, adicione uma referência ao componente .NET chamado “Enterprise Library Logging Application Block”.

Edite o código de sua classe, que provavelmente foi criada em Program.cs, para esse:

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Logging;

using System.Diagnostics;

 

namespace LogSpike

{

    class Program

    {

        static void Main(string[] args)

        {

            LogEntry logEntry = new LogEntry();

            logEntry.Severity = TraceEventType.Error;

            logEntry.ProcessName = “ProcessoTeste”;

            logEntry.Categories.Add(“Erro”);

 

            Logger.Write(logEntry);

        }

    }

}

Execute a classe e você deverá ver a mensagem esperada no arquivo de log assim como no Event Viewer, dentro de “Application Log”.

Event Viewer

Você pode encontrar mais informações sobre o Logging Application Block aqui.

Protegendo suas informações

Sexta-feira, 13 de junho de 2008 por Luciano Coelho

A “Enterprise Library 4.0” é um conjunto de aplicações (application blocks) que foi criada para auxiliar o programador .NET em algumas situações complexas que surgem durante o desenvolvimento de uma aplicação. Cada bloco de aplicação pode ser utilizado individualmente sem a necessidade de se referenciar toda a biblioteca. Juntamente com o aplicativo de instalação é baixado também o código fonte que você pode adequar às suas necessidades.

O “Cryptography Application Block”, é uma mão na roda para quem precisa guardar informações com segurança ou garantir a integridade da informação.

Ele abstrai a implementação de dois tipos comuns de criptografia: symmetric (simétrica) e hash (pode ser traduzido como um resumo embaralhado da informação). A simétrica é utilizada para criptografar o texto de através de uma chave secreta de modo que possa ser recuperado posteriormente com o uso da mesma chave.  O hash é utilizado para garantir, por comparação, que uma informação (seja um texto ou um arquivo) não tenha sido alterada no meio do caminho. Poderia escrever mais aqui sobre criptografia, mas é um assunto extenso. Então, deixemos essa parte para os colaboradores da Wikipedia (links no final do post).

Configurando a aplicação

A maneira mais fácil e rápida de se configurar qualquer bloco na Enterprise Libray é utilizando a ferramenta de configuração que foi instalada junto com o pacote:

Abra o arquivo de configuração de seu projeto. Como exemplo, criamos uma aplicação web, então será o Web.Config.

Adicione uma nova seção de configuração conforme a figura:

Aparecerá:

Estão disponíveis as opções para criptografia simétrica e hash. Em nosso exemplo vamos utilizar a criptografia simétrica onde poderemos criptografar e descriptografar uma informação. Criamos o “Symmetric Algorithm Provider” e escolhemos como algoritmo Rijndael (RijndaelManaged). 

Nesse momento abrirá o “Cryptographic Key Wizard” que o guiará na geração da chave que será utilizada para a criptografia. Com a chave gerada e armazenada em um arquivo, você deve protegê-la.

Selecione o modo de proteção:
- User mode: somente as aplicações rodando com o usuário logado terá acesso à chave para criptografar e descriptografar uma informação.
- Machine mode: qualquer aplicação rodando na máquina (e somente naquela máquina) terá acesso à chave.

Caso o usuário seja deletado acidentalmente ou a máquina vá para o espaço, ou ainda, caso seja necessário rodar a aplicação em outra máquina, é possível exportar a chave, protegendo-a com uma senha e importá-la com a mesma senha em outra máquina ou para outro usuário.

Clique em “Finish”, escolha um nome para o provider criado, salve a configuração e pronto.  Vamos programar. 

Usando o  Cryptography Application Block

No Web.Config  você poderá notar o seguinte trecho. Estão definidos, o algoritmo, o local do arquivo que contém a chave, a proteção e o nome:

<securityCryptographyConfiguration>
    <symmetricCryptoProviders>
      <add algorithmType=System.Security.Cryptography…
        protectedKeyFilename=C:\Projetos\…
        protectedKeyProtectionScope=LocalMachine
        type=Microsoft.Practices.EnterpriseLibrary.Security…
        name=TesteCriptografiaProvider />
    </symmetricCryptoProviders>
</securityCryptographyConfiguration>

 

Adicione a referência ao projeto. Clique com o botão direito sobre o projeto no “Solution Explorer” do Visual Studio, em seguida em “Add Reference…”, encontre o assembly “Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll”, adicione também os assemblies “Microsoft.Practices.EnterpriseLibrary.Common.dll” e “Microsoft.Practices.EnterpriseLibrary.ObjectBuilder2.dll” e clique em OK.

 

Na classe em que for utilizar a criptografia, adicione a instrução “using” (C#): 
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;

 

Criptografando:
string msgCriptografada = Cryptographer.EncryptSymmetric(“TesteCriptografiaProvider”, “Mensagem Secreta”);

Descriptografando:
string msgRevelada = Cryptographer.DecryptSymmetric(“TesteCriptografiaProvider”, msgCriptografada);

Isso mesmo… Uma única linha para criptografar e outra para descriptografar.

Versões

Aqui foi utilizada a versão 4.0 da “Enterprise Library” desenvolvida para o Framework 3.5. Estão disponíveis as versões anteriores para o Framework 3.0, 2.0 e 1.1 também no endereço http://msdn.microsoft.com/en-us/library/cc467894.aspx.

Links

Sobre a Enterprise Library 4.0
http://msdn.microsoft.com/en-us/library/cc512464.aspx

Download
http://www.microsoft.com/downloads/details.aspx?FamilyId=90DE37E0-7B42-4044-99BE-F8ECFBBC5B65&displaylang=en

Criptografia
http://pt.wikipedia.org/wiki/Criptografia (português)
http://en.wikipedia.org/wiki/Cryptography (inglês – com mais informações)


Switch to our mobile site