.NET

3 jun, 2011

Extensibilidade e o MEF

Publicidade

A extensibilidade dentro da engenharia de software é algo que há muito é perseguido. Ou seja, ter softwares que sejam plugáveis, tendo assim uma flexibilidade maior e que seja fácil de modificar e estender mesmo em tempo de Execução. Como dito em outro artigo, a extensibilidade é algo que, quando utilizado com sabedoria, é uma ferramenta muito útil para criar arquiteturas flexíveis, que sejam, por exemplo, como um “Lego” em que exponho as peças que precisam e elas se acoplam no software facilmente.

A versão 4.0 do .NET Framework trouxe uma tecnologia chamada MEF – Microsoft Extensibility Framework. Um framework para criação de aplicativos extensíveis, uma tecnologia que veio para nos auxiliar a criar softwares que sejam plugáveis. Como em um “Lego”, no qual há peças que precisam de um “encaixe” e outras peças que se “encaixam” nas mesmas quando necessário. O MEF também pode ser utilizado como um container de injeção de dependência, servindo assim como ferramenta para realizar a inversão de controle.

Arquitetura do MEF

O MEF possui um design, em que a sua arquitetura é dividida em três partes: 1) a camada em que se encontram os containers, ou seja, os repositórios de objetos; 2) uma camada que direciona o MEF a descobrir as partes, através do que chamamos de Imports/Exports e 3) finalmente uma camada que contém um Modelo de objetos que são utilizados como atributos, em que os mesmos serão utilizados para decorar classes, propriedades e etc para que sejam encontradas as partes através de Imports/Exports. Veja a figura abaixo:

Mecanismo de trabalho do MEF

O MEF é uma excelente tecnologia para permitir extensibilidade nos aplicativos e torná-los aderentes a modelo de Plugin. A maneira como o MEF trabalha é ilustrada pela figura abaixo:

O MEF trabalha com catálogos de containers. Um container possui um conjunto de objetos, que é unido segundo um grafo das dependências entre os objetos, em que o MEF vai descobrir que objeto depende de qual e vai resolver essa dependência na ordem correta e manter esses objetos armazenados no container. Um container pode ser um assembly, um diretório remoto em que se encontram assemblyes ou até mesmo um arquivo XAP, no caso do silverlight. Dentro do MEF, um catálogo nada mais é do que um conjunto de containers. Um catálogo pode contar vários containers armazenados consigo.

Uma Part ou ComposablePart é uma unidade de composição dentro do MEF. Essa unidade de composição é uma instância de um objeto, que pode ser de importação/Import ou de Exportação/Export. Para que possa haver a composição, é necessário que exista pelo menos uma parte de exportação/Export. Uma Part ou ComposablePart é armazenada dentro de um container.

Para simplificar: o que eu preciso, eu Importo/Import e o que eu Ofereço, Exporto/Export. Veja o exemplo de código abaixo:

O que eu preciso eu importo, decoro a propriedade, por exemplo, com o atributo Import contendo o tipo do objeto que eu preciso. E quando tenho uma classe, que possui o que uma outra classe precisa, ela respeita um determinado contrato ou é de um determinado tipo. Decoro-a com o atributo Export contendo o tipo do objeto que estou exportando. Vale lembrar que uma parte não pode fazer referencia diretamente a outra parte, devemos trabalhar com contratos, como mostra a figura seguinte. O container utiliza as informações do contrato para igualar importação com exportação e assim definir uma Part ou ComposablePart. Uma observação a ser feita é que, quando um contrato não é especificado explicitamente, o MEF utiliza o nome completo da classe ( namespace + nome da classe ) como contrato.

O exemplo acima mostra o cenário ideal para se trabalhar com extensibilidade e o MEF. É definido um contrato, no caso a inteface ICacheManager, e ela é decorada com o atributo InheritedExport. Dessa forma, todas as classes que implementarem ICacheManager estarão aptas a serem utilizadas por alguma classe que precise de um gerenciador de cache. O MEF irá automaticamente descobrir e fornecer um à instância de um objeto que respeita o contrato da interface e passar a quem tem uma dependência para esse objeto. Abaixo, veremos como o MEF age, uma vez que o container interage com o catálogo para ter acesso às Parts ou ComposableParts, que combinam e expõem ao mundo exterior:

O MEF utiliza um agregador de catálogos, em que um catalogo é um diretório que contém dlls e o outro é o próprio assembly em que o programa está sendo executado. E nesses dois catálogos poderão ser pesquisadas as Parts, para que elas possam ser utilizadas.

O MEF é simples de usar, mas, embora simples, é extremamente poderoso como ferramenta para permitir extensibilidade em seus aplicativos. Em outro artigo, trabalharemos com MEF em um cenário mais real, e poder ter uma visão ainda mais clara do que se pode fazer com essa tecnologia.

Um abraço, pessoal, espero que tenham gostado do post, e que ele seja útil no dia a dia de cada um de vocês.

Até a próxima.