2017-11-28 8 views
1

Ich habe eine .Net4-Assembly, die eine abstrakte Basisklasse verfügbar macht. In derselben Assembly habe ich Code, der alle Dateien in einem Ordner widerspiegelt, um eine Liste von Klassen zu erstellen, die diese Basisklasse erben. Hier ist die ausgeprägte RoutineReflectionTypeLoadException und COM-Interop

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); 
    } 
} 

ich einen Komponententest haben, die diesen Code ausgeführt wird, einen bestimmten Ordner Targeting, und es funktioniert gut, eine Liste von Klassen Rückkehr der Basisklasse als JSON vererben.

Der obige Code befindet sich in einer Assembly, die von einer COM (VB6) -Komponente aufgerufen werden soll. Wenn ich jetzt denselben Code von COM aufrufe, der auf den gleichen Ordner abzielt, auf den der Unit-Test zielt, erhalte ich den Reflektionsfehler und die Loader-Info meldet, dass er die Assembly, die den obigen Code enthält, nicht laden kann. Das tritt nur in der GetLoadableTypes-Routine auf dem GetTypes()-Aufruf auf, wenn ich über eine Assembly nachdenke, die Klassen enthält, die die Basisklasse erben.

Es klingt fast wie ein Re-Entrance-Problem, das nur auftritt, wenn COM beteiligt ist. Ich denke, ich könnte die abstrakte Basisklasse in eine andere Baugruppe einfügen, aber ich fragte mich, ob da noch etwas anderes vor sich ging.

Jede Erklärung oder Zeiger offensichtlich erhielt dankbar

Fehlermeldung:

Reflection „. Können Sie eine oder mehrere der angeforderten Typen laden Rufen Sie die Loaderexceptions-Eigenschaft für mehr Informationen“

und in der Loaderexceptions:

„kann nicht Datei oder Assembly laden 'IfxGenDocService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' oder eine ihrer Abhängigkeiten Die . System kann die angegebene Datei nicht finden. ":" IfxGenDocService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null“

EDIT1: ich änderte die Dinge ein wenig herum, die Basisklasse in seinen eigenen Arsch zu extrahieren embly und bekomme immer noch den gleichen Fehler. Vielleicht relevant ist, dass ich eine Test-Assembly habe, die 3 Klassen enthält, die die Basisklasse erben. Ich bekomme 3 Loaderexceptions (alle die gleichen wie oben angegeben. I 1 für jede Klasse übernehmen.

+0

Können Sie die vollständige Fehlermeldung hinzufügen? – thehennyy

+0

Thx .. gerade hinzugefügt –

Antwort

1

Es kann auch passieren, wenn die Baugruppe durch einen Prozess gesperrt ist Die Methoden Assembly.LoadFile und Assmebly.LoadFrom sperren die Assembly, und wenn Sie diese Methode in einem Prozess mehrmals aufrufen, ist es möglich, diese Ausnahme beim zweiten Aufruf zu erhalten.

Sperre zu vermeiden, müssen Sie diese Zeile in Verzeichnissen befinden, wenn alle abhängigen Baugruppen arbeiten

.Select(f => Assembly.LoadFile(Path.Combine(path, f.Name))) 

mit

.Select(f => Assembly.Load(File.ReadAllBytes(Path.Combine(path, f.Name)))) 

ändern, in dem Sie durchlaufen werden, sonst kann man überprüfen System.Reflection.Assembly.LoadFile Locks File und Loading Assembly to Leave Assembly File Unlocked

+0

Ausgezeichnet. Viele Danke –

0

Das Problem war, mit dieser Linie

.Select(f => Assembly.LoadFile(Path.Combine(path, f.Name))) 

Es sollte eigentlich

gewesen
.Select(f => Assembly.LoadFrom(Path.Combine(path, f.Name))) 

Seit Loadfrom lädt auch Abhängigkeiten Ich gehe davon aus, dass beim Ausführen von Komponententests die Abhängigkeiten bereits geladen worden sind

Verwandte Themen