MEF como IoC/DI Container

O .NET 4 vem com uma biblioteca chamada MEF – Managed Extensibility Framework que, de acordo com sua definição, ajuda os desenvolvedores a construir aplicações que suas partes são descobertas e construídas em tempo de execução. Na prática, são aplicações com partes “plugáveis”, através (obviamente) de plugins.

Só que é possível, sem muitas dificuldades, utilizar o MEF como um IoC/DI container, com o diferencial que não existe a obrigação de haver um artefato estático que faça o mapeamento dos tipos (por exemplo, um arquivo XML ou uma classe) como a maioria dos outros containers. Além disso, para utilizá-lo, basta importar o assembly System.ComponentModel.Composition do .NET, sem a necessidade de instalar uma biblioteca externa.

Para utilizar o MEF, você precisa basicamente de quatro elementos: Um contrato, um import, um export e um catálogo.

– O contrato é o ponto comum entre um import e um export, e indica a funcionalidade esperada de uma parte. Normalmente é definido através de uma interface, mas pode ser um tipo abstrato, por exemplo.
– O import é onde a parte será plugada, que pode ser uma propriedade, uma coleção (no caso de se esperar várias implementações do mesmo contrato) ou construtor de uma classe. É definido através do atributo [Import] ou [ImportMany]
– O export é o plugin (a parte que será plugada) que contém a implementação da funcionalidade definida pelo contrato. É definido pelo atributo [Export].
– O catálogo contém os tipos exportados e que podem ser utilizados para satisfazer Imports de cada contrato. O MEF vem com quatro tipos de catálogos: DirectoryCatalog (busca os tipos exportados nos assemblies em um determinado diretório – p.e. d:\app\plugins\), AssemblyCatalog (todos os tipos de um assembly), TypeCatalog (você especifica explicitamente quais tipos compoem o catálogo) e AggregateCatalog (permite combinar vários catálogos). Existem diversos outros tipos de catálogos que podem ser encontrados na internet, inclusive alguns que usam mapeamento XML. Os catálogos são utilizados pelo container no MEF (CompositionContainer) para criação dos tipos.

Para quem se interessar, o link abaixo leva a uma série de posts detalhando melhor como utilizar a biblioteca:
http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-toc.aspx

O MEF também tem uma mecânica interessante para lidar com o tempo de vida os objetos. Resumidamente, você pode especificar se a instância é compartilhada (singleton) ou exclusiva no momento da importação ou na exportação dos tipos. Neste link, um dos desenvolvedores da biblioteca (que por sinal é o criador do Castle) explica como trabalhar com esta questão.

Windows 8 vai suportar nativamente XAML

Ao divulgar mês passado o Windows 8 e suas aplicações construídas em HTML5 + JS , a Microsoft deixou muitos dos seus desenvolvedores .NET preocupados: iria a Microsoft abandonar o modelo .NET de desenvolvimento de aplicações e focar somente nas tecnologias Web? A Microsoft não diz nada, apenas fala para os desenvolvedores esperaram o evento BUILD em setembro desde ano, onde todas as respostas seriam dadas.

Só que algumas pessoas analisaram os arquivos de builds do Windows 8 que vazaram na Web e descobriram algumas coisas:

  • O Windows 8 virá com a versão 4.5 do .NET Framework
  • Haverá uma nova API do Windows chamada WinRT
  • E um nova camada de UI será disponibilizada para a construção de aplicativos gráficos, chamada Jupiter, baseada em XAML
Ou seja, o XAML saiu dos domínios do WPF (.NET),  Silverlight e WP7 e passa a ser um elemento nativo do sistema operacional.
Mais informações nos links abaixo:

Tutorial WPF MVVM no Youtube

Passei o dia inteiro de hoje na internet buscando exemplos, documentos e tutoriais para entender melhor a arquitetura MVVM (Model View View-Model) que é utilizada no Windows Presentation Foundation (WPF). Conceitualmente é fácil de entender, principalmente se você já trabalhou com outros padrões como o MVC (Model View Controler). Mas pra quem vem do Windows Forms, pode ser uma mudança de cultura significativa.

Resumindo a missa, o MVVM prega a divisão de sua aplicação WPF em três camadas:

  • Model – Modelo de dados, suas entidades de domínio. Podem ser entidades POCO ou geradas por alguma ferramenta a partir da base de dados. No meu caso, estou utilizando as entidades geradas pelo Entity Framework;
  • View – A interface gráfica da tela, escrita em XAML. Não deve conter NENHUMA regra de negócio implementada, apenas exibição. A View também não deve conhecer nada do modelo;
  • View-Model – Faz a ligação entre o modelo e a view. Contém a implementação das regras de negócio, expõe as propriedades, listas, comandos e demais recursos utilizados pela View.
As vantagens deste modelo são a grande organização no código, diminuição do acoplamento e com isso, aumento da reutilização, possibilidade de equipes paralelas trabalhando em uma tela sem necessidade de trocas de informação (ex: designers não precisam conhecer o modelo detalhadamente para desenhar a tela), dentre outras.
Voltando ao assunto, depois de ler e ver muita coisa, encontrei uma série de vídeos no youtube onde o apresentador implementa do zero uma aplicação WPF / MVVM, juntamente com Entity Framework e WCF. Muito bom e didático o exemplo, e cobre basicamente tudo que é necessário para se trabalhar com este padrão. São no total 8 vídeos, sendo que o link para o primeiro segue abaixo.

Depois é só seguir os links relacionados do youtube ou ir nos vídeos do usuário (em http://www.youtube.com/user/rainerstropek).

No último vídeo, ele demonstra a reutilização do ViewModel para recriar a mesma aplicação em Silverlight (que utiliza XAML). Muito interessante!

Envio de logs por e-mail com a EntLib

Utilizando o Logging Application Block da Enterprise Library, é possível configurar sua aplicação para enviar e-mails em casos de logs específicos. Isso é feito de forma transparente para a aplicação, através dos filtros de log que são definidos no arquivo de configuração. O e-mail é uma forma ativa de log, que não depende de alguém que fique monitorando os logs da aplicação. Mas é importante saber quando deve-se enviar e-mails, para que não sejam geradas muitas mensagem, o que tornaria o monitoramento ineficiente.

Com a EntLib, é possível escolher a maneira de se logar (listener de log) pela severidade e pela categoria dos logs. Em algumas aplicações críticas, pode-se configurar o serviço para enviar um e-mail com detalhes do log em casos de falhas de severidade Critical (a mais severa). Podem ser consideradas críticas as falhas que a aplicação não consegue se recuperar. Os demais logs podem ser armazenados no banco de dados ou arquivos.

Portanto, será enviado um e-mail se em algum trecho do código houver uma chamada de log como no exemplo abaixo:

Logger.Write(string.Format("A critical failure occurred: {0} - Stack: {1}", ex.Message, ex.StackTrace), "Start", 0, 0, TraceEventType.Critical, "AppContext");

Para configurar, é necessário adicionar no arquivo de configuração o listener de e-mail, na seção loggingConfiguration:

    <listeners>
      <add toAddress="alerta@dominio.com.br" fromAddress="aplicacao@dominio.com.br"
        subjectLineStarter="[" subjectLineEnder="] Application Log"
        smtpServer="mail.dominio.com.br" smtpPort="587" formatter="Text Formatter"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        traceOutputOptions="None" filter="Critical" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

        name="Email TraceListener" />
        (...)
    </listeners>

Note que na propriedade filter, o valor configurado está Critical. Para adequar o texto do log ao formato do e-mail, definimos um formatter:

    <formatters>
      <add template="Log date (local): {timestamp(local:yyyy-MM-dd HH:mm:ss.fff)}Category: {category}Operation: {title}Server: {machine}Parameters: {dictionary({key}={value};)}Message: {message}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        name="Text Formatter" />
        (...)
    </formatters>

Se o servidor exiger autenticação, é necessário adicionar as credenciais de acesso no arquivo de configuração, dentro da seção system.net:

  <system.net>
    <mailSettings>
      <smtp from="aplicacao@dominio.com.br">
        <network host="mail.dominio.com.br" port="587" userName="aplicacao" password="123456" />
      </smtp>
    </mailSettings>
  </system.net>