Ich habe Probleme mit CreateInstanceAndUnwrap im Moment aus irgendeinem Grund (arbeitete vorher).CreateInstanceAndUnwrap in einer anderen Domäne?
Mein Verfahren ist folgende:
ich dynamisch einen Code generieren und es lädt DLL aus einem Unterverzeichnis über MEF. Diese Anwendungen laden dann verschiedene Teile (auf Anfrage) von diesen DLLs. Ich musste meinen Code aktualisieren, um jetzt ein AppDomainSetup einzuschließen, das den Pfad der aufrufenden Assembly enthält.
Ich erstelle die neue AppDomain korrekt - keine Probleme. Wenn ich versuche, diesen Code auszuführen:
object runtime = domain.CreateInstanceAndUnwrap(
typeof(CrossDomainApplication).Assembly.FullName,
typeof(CrossDomainApplication).FullName);
Ich habe massive Probleme - die Laufzeit (variable oben) nicht mehr zu CrossDomainApplication oder ICrossDomainApplication werfen können.
Das eigentliche Objekt wie folgt aussieht:
public class CrossDomainApplication : MarshalByRefObject, ICrossDomainApplication
Und die Schnittstelle wie folgt aussieht:
public interface ICrossDomainApplication
{
void Run(CrossDomainApplicationParameters parameters);
}
und die Parameter wie folgt aussehen:
[Serializable]
public class CrossDomainApplicationParameters : MarshalByRefObject
{
public object FactoryType { get; set; }
public Type ApplicationType { get; set; }
public string ModuleName { get; set; }
public object[] Parameters { get; set; }
}
Die native Art der Laufzeit erscheint sei MarshalByRefObject - und es mag keine Konvertierung in etwas anderes.
Irgendwelche Gedanken zu was könnte falsch sein?
EDIT: Hier ist der Fehler, den ich bekomme, wenn ich es wie folgt ausgeführt werden:
ICrossDomainApplication runtime = (ICrossDomainApplication)domain.CreateInstanceAndUnwrap(
typeof(CrossDomainApplication).Assembly.FullName,
typeof(CrossDomainApplication).FullName);
//Exception before reaching here
runtime.Run(parameters);
System.InvalidCastException: Kann nicht transparenten Proxy eingeben ‚Infrastructure.ICrossDomainApplication‘ werfen.
Hier ist, was die Domain aussieht, wie ich es schaffen:
AppDomain domain = AppDomain.CreateDomain(
Guid.NewGuid().ToString(),
null,
new AppDomainSetup()
{
ApplicationBase = GetPath(),
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
LoaderOptimization = LoaderOptimization.MultiDomainHost
});
und GetPath() sieht wie folgt aus:
private string GetPath()
{
Uri path = new Uri(Assembly.GetCallingAssembly().CodeBase);
if (path.IsFile)
{
path = new Uri(path, Path.GetDirectoryName(path.AbsolutePath));
}
return path.LocalPath.Replace("%20", " ");
}
Könnte so einfach sein, dass die CLR die Baugruppe nicht findet. Überspringe nicht die Dokumentation der exakten * Ausnahme, die du bekommst. –
Es scheint keine Ausnahmen zu geben - abgesehen von meinem obigen Idealfall, wo ich es einfach auf den gewünschten Typ gewirkt habe. Ich habe auch Handler angefügt, um Ereignisrückruf auf AppDomain.Current, sowie die neue Domäne zu protokollieren. Es gibt keine Ausnahmen oder Rückrufe, es sei denn, ich versuche es schnell umzusetzen. – Locke
Dies ist ein sehr häufiges Problem mit Plugins. Sie haben ** zwei ** Definitionen für ICrossDomainApplication. Sie kamen von * verschiedenen * Versammlungen. Entweder, weil Sie eine Assembly kopiert haben oder weil Sie den Quellcode zweimal eingefügt haben. Die CLR behandelt sie als separate und inkompatible Typen. Sie müssen sicherstellen, dass dieselbe Assembly mit der One-and-Only-ICrossDomainApplication in beide Anwendungsdomänen geladen wird. –