Why is my MEF part not visible to plugin hosts?

◇◆丶佛笑我妖孽 提交于 2021-01-27 06:41:19

问题


I have a small class that performs a data import from a client. Each client has their own version of this class, so it is an MEF plugged in part:

[Export(typeof(IXTImportEmployeePrePlugin))]
public class PreEmployeeImport : XTImportEmployeePrePlugin

Yet when I try and import the plugin, like so:

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + PluginDir);

The resultant catalog has 1 file and 0 parts, yet the part is in the file. I've checked with dotPeek.

What could cause the host to not see the exported part? Another tiny test host I wrote also imports the plugin assembly and it sees the part fine.


回答1:


That is probably because the assembly is not loaded.

I'll describe the process that takes place once you call the constructor of a DirectoryCatalog

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "second");

Internall the method Initialize is called and that does basically two things. It enumerates the *.dll files and after that it calls Assembly.Load on all of them.
When Initialize is finished the collections LoadedFiles and Parts are hopefully populated.

The property LoadedFiles is misguiding the debug effort because having a file in that collection doesn't mean the Assembly did actually get loaded, it only tells that one or more files named '*.dll' where found in that folder. So LoadedFiles is better thought of as FoundFiles.

After the LoadedFiles are collected the actually loading of the assumed assemblies take place. Every found file is fed into Assembly.Load. Whenever this fails you'll end up with no types in the Parts collection.

I've reproduced your situation by having an x86 console app trying to load an x64 dll having my Export types. As these are simple fusion issue's I used the Fusion Log Viewer to diagnose. My scenario showed the following error:

The operation failed. Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format.

In the documentation 3 main reasons are given for not loading asemblies:

  • The part is in an EXE file. The default DirectoryCatalog reads only from DLL files. You can use a DirectoryCatalog to read from other files by creating it with the appropriate search pattern.
  • The part's assembly has a missing reference. Assemblies used must be able to load their references from the search path, usually either from their own directory or from the global assembly cache.
  • The part's assembly targets a different CPU type. MEF will not load assemblies targeting the wrong CPU type.

Not knowing how your host application/appdomain looks like you might need this article that describes how to diagnose fusion issues. It is for v2 of the framework but some might still be relevant. The following paragraphs are an excerpt from that article:

For BadImageFormatException:
Try running peverify.exe on the file.

For SecurityException:
You need Execute permission for loading any assembly.

For FileLoadException:

  • For an "Access is denied" message (for hresult E_ACCESSDENIED, 0x80070005):
    Run tlist -m on the file to see if another process has the file locked and without share-read access.

  • For a "The located assembly's manifest definition with name [yourAssembly] does not match the assembly reference" message (for hresult FUSION_E_REF_DEF_MISMATCH, 0x80131040):
    The Fusion log will say which part of the assembly reference failed to match what was found. It will be the assembly name, culture, public key (or token) or version (if the found assembly was strongly-named).

  • For "Unverifiable image [yourAssembly] can not be run" or "Can not run executable [yourAssembly] because it contains relocations" messages (for hresult COR_E_FIXUPSINEXE, 0x80131019):
    That image must be run as the process exe or else be compiled as a dll. This is because MC++ has made optimizations for you in your image, based on the assumption that it will be the process exe.



来源:https://stackoverflow.com/questions/20840067/why-is-my-mef-part-not-visible-to-plugin-hosts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!