Ich habe eine Anwendung, die Assemblys lädt und nach Typen sucht, die Unterklassen einer Klasse C1 sind, die in einer anderen Assembly A1 definiert sind, auf die die Anwendung verweist. Ich habe einen Typ T in A1 definiert, der eine Unterklasse von C1 ist, aber wenn ich A1 mit Assembly.Load (...) lade, dann rufe t.IsSubclassOf (typeof (C1)) für eine Instanz von T I auf false. Ich habe bemerkt, dass es zwei Instanzen der Assembly A1 in der aktuellen Appdomain gibt und t.IsSubclassOf (C1) funktioniert, wenn ich den Typ C1 aus einer der Instanzen nehme, aber nicht beides. Ich verstehe dieses Verhalten nicht ganz, kann mir jemand erklären? Außerdem, wie kann ich meine App reparieren, so dass dies funktioniert, ob A1 oder eine andere Assembly geladen wird, um nach Untertypen von C1 zu suchen?Type.IsSubclassOf verhält sich nicht wie erwartet
Antwort
Damit die CLR Typen eindeutig identifizieren kann, enthält sie Assemblierungsinformationen in der Typkennung. Ihr Problem ist, dass die CLR die beiden Instanzen von A1 als unterschiedliche Baugruppen klassifizieren, daher sind Sie effektiv ausführen:
A1::T1.IsSubClassOf(A1Copy::C1) // No relationship between A1 and A1Copy
... statt:
A1::T1.IsSubClassOf(A1::C1)
Baugruppe eindeutig identifiziert wird durch seine Name, Version, Kultur und öffentlicher Schlüssel. Bitte überprüfen Sie diese Werte (über Assembly.GetName()
) von beiden Assembly-Instanzen in der App-Domäne; Ich vermute, dass in einem der Attribute eine Diskrepanz besteht, die dazu führt, dass die CLR die anstößige Assembly lädt.
Ja, ich mit diesem gerade gebaut zwei Projekte, definiert ich in einem Projekt Eltern und Kind Klassen:
namespace ClassLibrary1
{
public class Parent
{
public string name;
}
public class Child : Parent
{
}
}
und dann versucht, die Informationen zu laden:
{
Type parent = typeof(Parent);
Type c1 = typeof(Child);
bool isChild1 = (c1.IsSubclassOf(parent).ToString());
Assembly a = Assembly.Load(File.ReadAllBytes("ClassLibrary1.dll"));
Type c2 = a.GetType(c1.FullName);
bool isChild2 = (c2.IsSubclassOf(parent).ToString());
}
und ich habe isChild1 ist wahr und isChild2 ist falsch.
Checking out diesen Link von Suzanne Cook Laden Contexts etwas mehr Licht zur Verfügung gestellt:
Die AppDomain, die Ihnen die Montage sind dem Laden in (mit Assembly.Load()
) Probleme verursachen könnte.
Verwenden Sie statt Assembly.Load()
AppDomain.CurrentDomain.Load()
. Dadurch wird sichergestellt, dass die Assembly in CurrentDomain geladen wird, wo Sie sie tatsächlich verwenden können.
Schauen Sie sich diesen Artikel für weitere Informationen:
http://blogs.microsoft.co.il/blogs/sasha/archive/2007/03/06/Assembly-Load-Contexts-Subtleties.aspx
Ich folgte Ihrem ersten Link und bekam eine StackOverflowException. –
Es auf dem Load-Kontext basiert, warum er sich nicht gleich bekommen. http://blogs.microsoft.co.il/blogs/sasha/archive/2007/03/06/Assembly-Load-Contexts-Subletties.aspx – user7116