Escolhendo entre MEF e MAF (System.AddIn)

O Managed Extensibility Framework (MEF) e Managed AddIn Framework (MAF, também conhecido como System.AddIn) parecem realizar tarefas muito semelhantes. De acordo com essa pergunta do Stack Overflow, o MEF é um substituto do System.Addin? , você pode até usar os dois ao mesmo tempo.

Quando você escolheria usar um contra o outro? Em que circunstâncias você escolheria usar os dois juntos?

Eu tenho avaliado essas opções e aqui está a conclusão a que cheguei.

O MAF é um verdadeiro framework addon. Você pode separar seus complementos completamente, até mesmo executá-los dentro de um domínio de aplicativo separado, de forma que, se um addon travar, ele não derrubará seu aplicativo. Ele também fornece uma maneira muito completa de dissociar os addons de depender de qualquer coisa, exceto do contrato que você lhes dá. Na verdade, você pode versionizar seus adaptadores de contrato para fornecer compatibilidade com versões anteriores aos complementos antigos enquanto atualiza o aplicativo principal. Embora isso pareça ótimo, ele tem um preço alto que você precisa pagar para cruzar os appdomains. Você paga esse preço em velocidade e também na flexibilidade dos tipos que você pode enviar e para trás.

O MEF é mais parecido com a injeção de dependência com alguns benefícios adicionais, como a descoberta e … (desenhando um espaço em branco neste). O grau de isolamento que o MAF tem não está presente no MEF. Eles são dois frameworks diferentes para duas coisas diferentes.

O que Danielg disse é bom. Eu adicionaria:

Se você assistir aos vídeos sobre o System.Addins, eles estão claramente falando sobre projetos muito grandes. Ele fala sobre uma equipe gerenciando o aplicativo host, outra equipe gerenciando cada AddIn e uma terceira equipe gerenciando o contrato e o pipeline. Com base nisso, acho que o System.Addins é claramente para aplicativos maiores. Estou pensando em aplicativos como sistemas ERP como o SAP (talvez não tão grande assim, mas você entendeu). Se você assistiu a esses vídeos, pode perceber que a quantidade de trabalho para usar o System.Addins é muito grande. Funcionaria bem se você tivesse muitas empresas programando suplementos de terceiros para o seu sistema e você não pode quebrar nenhum desses contratos adicionais sob pena de morte.

Por outro lado, o MEF parece compartilhar mais semelhanças com o esquema de suplemento do SharpDevelop, a arquitetura de plug-in do Eclipse ou o Mono.Addins. É muito mais fácil de entender do que System.Addins e acredito que seja muito mais flexível. As coisas que você perde são que você não obtém o isolamento do AppDomain ou contratos de versão fortes prontos para uso com o MEF. Os pontos fortes do MEF são que você pode estruturar todo o seu aplicativo como uma composição de peças, para que você possa enviar seu produto em diferentes configurações para diferentes clientes, e se o cliente comprar um novo recurso, basta soltar a peça desse recurso no diretório de instalação. e o aplicativo o vê e o executa. Isso também facilita o teste. Você pode instanciar o object que deseja testar e alimentá-lo a objects de simulação para todas as suas dependencies, mas quando ele é executado como um aplicativo composto, o processo de composição conecta automaticamente todos os objects reais.

O ponto mais importante que gostaria de mencionar é que, embora o System.Addins já esteja no framework, não vejo muitas evidências de pessoas usando ele, mas o MEF está apenas sentado lá no CodePlex, supostamente incluído no .NET 4, e as pessoas já estão começando a construir muitas aplicações com ele (inclusive eu). Eu acho que isso diz algo sobre os dois frameworks.

Tendo desenvolvido e enviado um aplicativo MAF. Minhas opiniões sobre o MAF estão um pouco cansadas.

O MAF é um sistema “desacoplado” ou um sistema “fracamente acoplado” na pior das hipóteses. O MEF é um sistema “acoplado” ou, na melhor das hipóteses, um sistema “fracamente acoplado”.

Os benefícios do MAF que percebemos usando o MAF são:

  1. Instalando novos ou atualizando componentes existentes enquanto o aplicativo está em execução. O AddIn pode ser atualizado enquanto o aplicativo estava em execução e as atualizações aparecem para o usuário sem problemas. Você tem que ter AppDomains para isso.

  2. Licenciamento baseado em componentes comprados. Poderíamos controlar quais AddIn foram carregados pela function e permissions do usuário e se o AddIn foi licenciado para uso.

  3. Desenvolvimento rápido (time-to-market mais rápido). O desenvolvimento do AddIn se encheckbox perfeitamente com a metodologia Agile, a equipe de desenvolvimento desenvolveu um AddIn de cada vez sem ter que também desenvolver a peça de integração com o restante do aplicativo.

  4. Melhoria do controle de qualidade (somente controle de qualidade, um componente por vez). O QA pode então testar e emitir defeitos para um único bit de funcionalidade. Os casos de teste foram mais fáceis de desenvolver e implementar.

  5. Implantação (adicionar componentes à medida que são desenvolvidos e liberados e eles “simplesmente funcionam”). A implantação é apenas uma questão de fazer um suplemento e instalar o arquivo. Nenhuma outra consideração foi necessária!

  6. Novos componentes trabalhavam com componentes antigos. AddIn que foram desenvolvidos no início continuaram funcionando. Novos AddIns se encheckboxm perfeitamente no Aplicativo

Na minha opinião, as duas tecnologias visam casos de uso muito diferentes.

O MEF normalmente é melhor em um cenário de injeção de dependência pura, em que a pessoa ou o grupo que fornece a solução integrada final está montando tudo e garantindo a integridade geral, mas precisa ter implementações diferentes dos principais resources.

O MAF é para um cenário em que alguém / grupo está desenvolvendo uma plataforma ou host e outros grupos adicionarão resources após o fato e de maneira que não estejam sob o controle do grupo de hosts. Nesse cenário, a necessidade é de mecanismos mais elaborados para “proteger” o host de suplementos invasores (ou para proteger suplementos uns dos outros).

Uma terceira tecnologia similar em padrão é todo o esquema ProviderBase. Isso também permite a substituição de um recurso, mas seu objective é realmente o cenário em que o host / aplicativo precisa absolutamente de uma capacidade e a necessidade é realmente especificar implementações diferentes via config.

Acabei de encontrar este longo artigo discutindo tanto o MAF quanto o MEF. http://emcpadden.wordpress.com/2008/12/07/managed-extensibility-framework-and-others/

Além dos pontos apresentados pelas outras respostas, parece que uma das principais diferenças entre o MEF e o MAF é que o Managed Extensibility Framework permitiria que uma parte composta dependesse de outra. Isso deixaria um plug-in depender de outro plug-in, por exemplo.

O Managed Extensibility Framework também não faz distinções entre o host e o add-in, como faz o System.AddIn. No que diz respeito ao MEF, todas elas são apenas partes compostas.

Na minha opinião, a melhor maneira de descobrir as diferenças é um código prático. Eu encontrei dois MSDN walkthroughs, ambos com um exemplo de calculadora para que você possa comparar facilmente suas implementações:

MEF: Exemplo de calculadora simples usando peças MEF
( E xensibilidade gerenciada)

  • Mostra como construir uma calculadora simples usando a tecnologia MEF. Não mostra como carregar DLLs externas. (Mas você pode simplesmente modificar o exemplo usando catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.dll")); vez de usar catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly)); e extraia o código da calculadora e o contrato para separar os projetos DLL.)
  • O MEF não precisa ter uma estrutura de diretórios específica, é simples e direta de usar, mesmo para projetos pequenos. Trabalha com atributos, para declarar o que é exportado, o que é fácil de ler e entender. Exemplo: [Export(typeof(IOperation))] [ExportMetadata("Symbol", '+')] class Add: IOperation { public int Operate(int left, int right) { return left + right; } } [Export(typeof(IOperation))] [ExportMetadata("Symbol", '+')] class Add: IOperation { public int Operate(int left, int right) { return left + right; } }

  • O MEF não lida automaticamente com versionamento

MAF: Calculadora simples com plugins MAF versão V1 e V2
(Ramed A ddin F de M anaged)

  • Mostra como construir a calculadora usando um plugin V1 e, em seguida, como passar para um plugin V2, mantendo a compatibilidade com versões anteriores ( observação: você pode encontrar a versão V2 do plugin aqui , o link no artigo original está quebrado)
  • O MAF impõe uma estrutura de diretórios específica e precisa de muito código clichê para fazê-lo funcionar, portanto, não o recomendo para projetos pequenos. Exemplo:
     Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters 

O MEF e o MAF estão incluídos no .NET Framework 4.x. Se você comparar os dois exemplos, você notará que os plug-ins do MAF têm muito mais complexidade em comparação com a estrutura do MEF – portanto, é necessário pensar cuidadosamente quando usar quais desses frameworks.

MAF e MEF ambos podem usar AppDomains e ambos podem carregar / descarregar dll em tempo de execução. No entanto, as diferenças que eu encontrei são: MAF AddIns são desacoplados, os componentes MEF são soltos; MAF “Activates” (nova instância) enquanto o MEF cria instâncias por padrão.

Com o MEF, você pode usar o Generics para fazer o GenericHost para qualquer contrato. Isso significa que o gerenciamento de carga / descarga e componente do MEF pode estar em uma biblioteca comum e usado genericamente.