mardi 28 novembre 2017

ReflectionTypeLoadException and COM-Interop

I have a .Net4 assembly which exposes an abstract, base class. In that same assembly, I haver some code which reflects over all the files in a folder to build up a list of classes inheriting that base class. Here's the salient routine

private JsonTextWriter GetAvailableServices(JsonTextWriter writer, string path)
    {
        try
        {            
            writer.WriteStartArray();
            writer = new DirectoryInfo(path).GetFiles(FileFilter)
                                            .Where(f => IsAssembly(f.FullName))
                                            .Select(f => Assembly.LoadFile(Path.Combine(path, f.Name)))
                                            .SelectMany(a => GetLoadableTypes(a))
                                            .Where(p => typeof(ServiceProxy).IsAssignableFrom(p) && !p.IsAbstract)
                                            .Select(a0 => new { Instance = Activator.CreateInstance(a0), ClassName = a0.ToString() })
                                            .Aggregate(writer, (s, v) =>
                                            {
                                                s.WriteStartObject();
                                                s.WritePropertyName(ClassnameLabel);
                                                s.WriteValue(v.ClassName);
                                                s.WritePropertyName(DescriptionLabel);
                                                s.WriteValue(((ServiceProxy)v.Instance).Description);
                                                s.WriteEndObject();
                                                return s;
                                            });                
        }
        catch { Exception ex; }
        finally
        {
            writer.WriteEndArray();                
        }

        return writer;
    }

 private IEnumerable<Type> GetLoadableTypes(Assembly assembly)
    {            
        try
        {
            return assembly.GetTypes();
        }
        catch (ReflectionTypeLoadException e)
        {
            return e.Types.Where(t => t != null);
        }
    }       

I have a unit test which runs this code, targetting a specific folder, and it all works fine returning a list of classes inheriting the base class as JSON.

The above code sits in an assembly which is to be invoked from a COM (VB6) component. If I now invoke this same code from COM, targetting the same folder which the unit test targets, I get the reflection error and the loader info reports that it can't load the assembly which contains the above code. This only occurs in the GetLoadableTypes routine on the GetTypes() call when I am reflecting over an assembly which contains classes which do inherit the base class.

It sounds almost like a re-entrancy issue which only arises when COM is involved. I guess I could put the abstract base class into another assembly but wondered if there was something else going on.

Any explanation or pointers obviously gratefully received





Aucun commentaire:

Enregistrer un commentaire