MEF: “Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information”

前端 未结 3 620
抹茶落季
抹茶落季 2020-12-25 15:03

Scenario: I am using Managed Extensibility Framework to load plugins (exports) at runtime based on an interface contract defined in a separate dll. In my Visual Studio solut

相关标签:
3条回答
  • 2020-12-25 15:35

    This issue can be caused by several factors (any exceptions on the loaded assemblies), like the exception says, look at the ExceptionLoader to (hopefully) get some idea

    Another problem/solution that I found, is when using DirectoryCatalog, if you don't specify the second parameter "searchPattern", MEF will load ALL the dlls in that folder (including third party), and start looking for export types, that can also cause this issue, a solution is to have a convention name on all the assemblies that export types, and specify that in the DirectoryCatalog constructor, I use *_Plugin.dll, that way MEF will only load assemblies that contain exported types

    In my case MEF was loading a NHibernate dll and throwing some assembly version error on the LoaderException (this error can happen with any of the dlls in the directory), this approach solved the problem

    0 讨论(0)
  • 2020-12-25 15:38

    Here is an example of above mentioned methods:

    var di = new DirectoryInfo(Server.MapPath("../../bin/"));
    
            if (!di.Exists) throw new Exception("Folder not exists: " + di.FullName);
    
            var dlls = di.GetFileSystemInfos("*.dll");
            AggregateCatalog agc = new AggregateCatalog(); 
    
            foreach (var fi in dlls)
            {
                try
                {
                    var ac = new AssemblyCatalog(Assembly.LoadFile(fi.FullName));
                    var parts = ac.Parts.ToArray(); // throws ReflectionTypeLoadException 
                    agc.Catalogs.Add(ac);
                }
                catch (ReflectionTypeLoadException ex)
                {
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }
    
            CompositionContainer cc = new CompositionContainer(agc);
    
            _providers = cc.GetExports<IDataExchangeProvider>();
    
    0 讨论(0)
  • 2020-12-25 15:52

    I have also run into a similar problem.

    If you are sure that you want to ignore such "bad" assemblies, then the solution is to call AssemblyCatalog.Parts.ToArray() right after creating each assembly catalog. This will trigger the ReflectionTypeLoadException which you mention. You then have a chance to catch the exception and ignore the bad assembly.

    When you have created AssemblyCatalog objects for all the "good" assemblies, you can aggregate them in an AggregateCatalog and pass that to the CompositionContainer constructor.

    0 讨论(0)
提交回复
热议问题