Assembly.GetTypes() - ReflectionTypeLoadException

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-30 11:48:45
Dan Bryant

A few things:

  • Make sure you don't have duplicate assemblies in the plugin directory (i.e. assemblies that you're already loading in your main app from your app directory.) Otherwise, when you load your plugin, it may load an additional copy of the same assembly. This can lead to fun exceptions like:

    Object (of type 'MyObject') is not of type 'MyObject'.

  • If you're getting the exception when instantiating a type, you may need to handle AppDomain.AssemblyResolve:

    private void App_Startup(object sender, StartupEventArgs e)
    {
        // Since we'll be dynamically loading assemblies at runtime, 
        // we need to add an appropriate resolution path
        // Otherwise weird things like failing to instantiate TypeConverters will happen
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }
    
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var domain = (AppDomain) sender;
    
        foreach (var assembly in domain.GetAssemblies())
        {
            if (assembly.FullName == args.Name)
            {
                return assembly;
            }
        }
    
        return null;
    }
    

I realize it's a bit strange to have to tell the CLR that, in order to resolve an assembly, find the assembly with the name we're using to resolve, but I've seen odd things happen without it. For example, I could instantiate types from a plugin assembly, but if I tried to use TypeDescriptor.GetConverter, it wouldn't find the TypeConverter for the class, even though it could see the Converter attribute on the class.


Looking at your edits, this is probably not what's causing your current exception, though you may run into these issues later as you work with your plugins.

Fábio Augusto Pandolfo

Thanks to this post I could solve the ReflectionTypeLoadException that I was getting in a UITypeEditor. It's a designer assembly (a winforms smart-tag used at design-time) of a custom class library, that scan for some types.

/// <summary>
/// Get the types defined in the RootComponent.
/// </summary>
private List<Type> getAssemblyTypes(IServiceProvider provider)
{
    var types = new List<Type>();
    try
    {
        IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
        ITypeResolutionService resolution = (ITypeResolutionService)provider.GetService(typeof(ITypeResolutionService));
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            foreach (var assembly in ((AppDomain)sender).GetAssemblies())
            {
                if (assembly.FullName == args.Name)
                {
                    return assembly;
                }
            }

            return null;
        };

        Type rootComponentType = resolution.GetType(host.RootComponentClassName, false);
        types = rootComponentType.Assembly.GetTypes().ToList();
    }
    catch
    {
    }

    return types;
}

You are getting an assembly version mismatch. Since your plugins refer to this libPublic.dll, you must version it carefully and in particular not bump its revision/build/etc. numbers at every compile.

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