Ferramenta de Análise de Composição (Mefx)Composition Analysis Tool (Mefx)
A Ferramenta de Análise de Composição (Mefx) é um aplicativo de linha de comando que analisa arquivos de biblioteca (.dll) e de aplicativo (.exe) que contêm partes do MEF (Managed Extensibility Framework).The Composition Analysis Tool (Mefx) is a command-line application that analyzes library (.dll) and application (.exe) files containing Managed Extensibility Framework (MEF) parts. A principal finalidade da Mefx é fornecer aos desenvolvedores uma maneira de diagnosticar falhas de composição em seus aplicativos MEF sem a necessidade de adicionar um código de rastreamento inconveniente ao próprio aplicativo.The primary purpose of Mefx is to provide developers a way to diagnose composition failures in their MEF applications without the requirement to add cumbersome tracing code to the application itself. Ele também pode ser útil para ajudar a entender as partes de uma biblioteca fornecida por terceiros.It can also be useful to help understand parts from a library provided by a third party. Este tópico descreve como usar a Mefx e fornece uma referência para sua sintaxe.This topic describes how to use Mefx and provides a reference for its syntax.
Obtendo a MefxGetting Mefx
A Mefx está disponível no GitHub em Managed Extensibility Framework.Mefx is available on GitHub at Managed Extensibility Framework. Basta baixar e descompactar a ferramenta.Simply download and unzip the tool.
Sintaxe básicaBasic Syntax
A Mefx é invocada na linha de comando no seguinte formato:Mefx is invoked from the command line in the following format:
mefx [files and directories] [action] [options]
O primeiro conjunto de argumentos especifica os arquivos e os diretórios dos quais as partes devem ser carregadas para análise.The first set of arguments specify the files and directories from which to load parts for analysis. Especifique um arquivo com a opção /file:
e um diretório com a opção /directory:
.Specify a file with the /file:
switch, and a directory with the /directory:
switch. Você pode especificar vários arquivos ou diretórios, conforme é mostrado no exemplo a seguir:You can specify multiple files or directories, as shown in the following example:
mefx /file:MyAddIn.dll /directory:Program\AddIns [action...]
Observação
Cada arquivo .dll ou .exe deve ser carregado somente uma vez.Each .dll or .exe should only be loaded one time. Se algum arquivo for carregado várias vezes, a ferramenta poderá retornar informações incorretas.If a file is loaded multiple times, the tool may return incorrect information.
Depois da lista de arquivos e diretórios, você deverá especificar um comando e as opções para esse comando.After the list of files and directories, you must specify a command, and any options for that command.
Listando as partes disponíveisListing Available Parts
Use a ação /parts
para listar todas as partes declaradas nos arquivos carregados.Use the /parts
action to list all the parts declared in the files loaded. O resultado é uma lista simple de nomes de parte.The result is a simple list of part names.
mefx /file:MyAddIn.dll /parts
MyAddIn.AddIn
MyAddIn.MemberPart
Para obter mais informações sobre as partes, use a opção /verbose
.For more information about the parts, use the /verbose
option. Isso produzirá mais informações para todas as partes disponíveis.This will output more information for all available parts. Para obter mais informações sobre uma única parte, use a ação /type
em vez de /parts
.To get more information about a single part, use the /type
action instead of /parts
.
mefx /file:MyAddIn.dll /type:MyAddIn.AddIn /verbose
[Part] MyAddIn.MemberPart from: AssemblyCatalog (Assembly=" MyAddIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
[Export] MyAddIn.MemberPart (ContractName=" MyAddIn.MemberPart")
Listando as importações e exportaçõesListing Imports and Exports
As ações /imports
e /exports
listarão todas as partes importadas e todas as partes exportadas, respectivamente.The /imports
and /exports
actions will list all the imported parts and all the exported parts, respectively. Você também pode listar as partes que importam ou exportam um tipo específico usando as ações /importers
ou /exporters
.You can also list the parts that import or export a particular type by using the /importers
or /exporters
actions.
mefx /file:MyAddIn.dll /importers:MyAddin.MemberPart
MyAddin.AddIn
Você também pode aplicar a opção /verbose
a essas ações.You can also apply the /verbose
option to these actions.
Localizando as partes rejeitadasFinding Rejected Parts
Depois de carregar as partes disponíveis, a Mefx usa o mecanismo de composição do MEF para compô-las.Once it has loaded the available parts, Mefx uses the MEF composition engine to compose them. As partes que não podem ser compostas com êxito são chamadas de rejeitadas.Parts that cannot be successfully composed are referred to as rejected. Para listar todas as partes rejeitadas, use a ação /rejected
.To list all the rejected parts, use the /rejected
action.
Você pode usar a opção /verbose
com a ação /rejected
para imprimir informações detalhadas sobre as partes rejeitadas.You can use the /verbose
option with the /rejected
action to print detailed information about rejected parts. No exemplo a seguir, a DLL ClassLibrary1
contém a parte AddIn
, que importa as partes MemberPart
e ChainOne
.In the following example, the ClassLibrary1
DLL contains the AddIn
part, which imports the MemberPart
and ChainOne
parts. A ChainOne
importa a ChainTwo
, mas a ChainTwo
não existe.ChainOne
imports ChainTwo
, but ChainTwo
does not exist. Isso significa que a ChainOne
foi rejeitada, o que faz com que a AddIn
seja rejeitada.This means that ChainOne
is rejected, which causes AddIn
to be rejected.
mefx /file:ClassLibrary1.dll /rejected /verbose
O exemplo a seguir mostra a saída completa do comando anterior:The following shows the complete output of the previous command:
[Part] ClassLibrary1.AddIn from: AssemblyCatalog (Assembly="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
[Export] ClassLibrary1.AddIn (ContractName="ClassLibrary1.AddIn")
[Import] ClassLibrary1.AddIn.memberPart (ContractName="ClassLibrary1.MemberPart")
[SatisfiedBy] ClassLibrary1.MemberPart (ContractName="ClassLibrary1.MemberPart") from: ClassLibrary1.MemberPart from: AssemblyCatalog (Assembly="ClassLibrar
y1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
[Import] ClassLibrary1.AddIn.chain (ContractName="ClassLibrary1.ChainOne")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No valid exports were found that match the constraint '((exportDefinition.ContractName == "ClassLibrary1.ChainOne") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "ClassLibrary1.ChainOne".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableParts, ImportDefinition id)
[Unsuitable] ClassLibrary1.ChainOne (ContractName="ClassLibrary1.ChainOne")
from: ClassLibrary1.ChainOne from: AssemblyCatalog (Assembly="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
[Because] PartDefinitionIsRejected, The part providing the export is rejected because of other issues.
[Part] ClassLibrary1.ChainOne from: AssemblyCatalog (Assembly="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
[Primary Rejection]
[Export] ClassLibrary1.ChainOne (ContractName="ClassLibrary1.ChainOne")
[Import] ClassLibrary1.ChainOne.chain (ContractName="ClassLibrary1.ChainTwo")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No valid exports were found that match the constraint '((exportDefinition.ContractName == "ClassLibrary1.ChainTwo") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "ClassLibrary1.ChainTwo".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableParts, ImportDefinition id)
As informações interessantes estão contidas nos resultados de [Exception]
e [Unsuitable]
.The interesting information is contained in the [Exception]
and [Unsuitable]
results. O resultado de [Exception]
fornece informações sobre por que uma parte foi rejeitada.The [Exception]
result provides information about why a part was rejected. O resultado [Unsuitable]
indica por que uma parte com outro tipo de correspondência não pôde ser usada para preencher uma importação. Nesse caso, porque essa parte foi rejeitada devido à ausência de importações.The [Unsuitable]
result indicates why an otherwise-matching part could not be used to fill an import; in this case, because that part was itself rejected for missing imports.
Analisando a causa principalAnalyzing Primary Causes
Se várias partes estiverem vinculadas em uma cadeia longa de dependência, um problema envolvendo uma parte próxima à parte inferior poderá fazer com que a cadeia inteira seja rejeitada.If several parts are linked in a long dependency chain, a problem involving a part near the bottom may cause the entire chain to be rejected. O diagnóstico desses problemas pode ser difícil, pois a causa raiz da falha nem sempre é óbvia.Diagnosing these problems can be difficult because the root cause of the failure is not always obvious. Para ajudar a resolver o problema, você pode usar a ação /causes
, que tenta localizar a causa raiz de qualquer rejeição em cascata.To help with the problem, you can use the /causes
action, which attempts to find the root cause of any cascading rejection.
O uso da ação /causes
no exemplo anterior listaria apenas as informações para ChainOne
, cuja importação não preenchida é a causa raiz da rejeição de AddIn
.Using the /causes
action on the previous example would list only information for ChainOne
, whose unfilled import is the root cause of the rejection of AddIn
. A ação /causes
pode ser usada nas opções normal e /verbose
.The /causes
action can be used in both normal and /verbose
options.
Observação
Na maioria dos casos, a Mefx poderá diagnosticar a causa raiz de uma falha em cascata.In most cases, Mefx will be able to diagnose the root cause of a cascading failure. No entanto, nos casos em que as partes são adicionadas de forma programática a um contêiner, nos que envolvem contêineres hierárquicos ou nos que envolvem implementações de ExportProvider
personalizadas, a Mefx não pode diagnosticar a causa.However, in cases where parts are added programmatically to a container, cases involving hierarchical containers, or cases involving custom ExportProvider
implementations, Mefx will not be able to diagnose the cause. Em geral, esses casos descritos devem ser evitados sempre que possível, pois as falhas geralmente são difíceis de diagnosticar.In general, the previously described cases should be avoided where possible, as failures are generally difficult to diagnose.
Listas de permissõesAllow lists
A opção /whitelist
permite que você especifique um arquivo de texto que lista as partes que devem ser rejeitadas.The /whitelist
option enables you to specify a text file that lists parts that are expected to be rejected. Assim, as rejeições inesperadas serão sinalizadas.Unexpected rejections will then be flagged. Isso pode ser útil quando você analisa uma biblioteca incompleta ou uma subbiblioteca que não tem algumas dependências.This can be useful when you analyze an incomplete library, or a sublibrary that's missing some dependencies. A opção /whitelist
pode ser aplicada às ações /rejected
ou /causes
.The /whitelist
option can be applied to the /rejected
or /causes
actions.
Considere um arquivo chamado test.txt que contenha o texto "ClassLibrary1.ChainOne".Consider a file named test.txt that contains the text "ClassLibrary1.ChainOne". Se você executar a /rejected
ação com a /whitelist
opção no exemplo anterior, ela produzirá a seguinte saída:If you run the /rejected
action with the /whitelist
option on the previous example, it produces the following output:
mefx /file:ClassLibrary1.dll /rejected /whitelist:test.txt
[Unexpected] ClassLibrary1.AddIn
ClassLibrary1.ChainOne