Ich verwende ein benutzerdefiniertes Framework, das Reflektion verwendet, um GetTypeByName(string fullName)
für den vollständig qualifizierten Typnamen, den es von der Datenbank erhält, zu erstellen, um eine Instanz dieses Typs zu erstellen und sie der Seite hinzuzufügen, was zu a führt Standard-Modularität der Sache.
GetTypeByName
ist eine Utility-Funktion von mir, die einfach durch Thread.GetDomain().GetAssemblies()
iteriert und dann einen assembly.GetType(fullName)
ausführt, um den relevanten Typ zu finden. Offensichtlich wird dieses Ergebnis für zukünftige Referenz und Geschwindigkeit zwischengespeichert.
Es treten jedoch einige Probleme auf, durch die, wenn web.config aktualisiert wird (und in einigen gruseligeren Fällen, wenn der Anwendungspool wiederverwendet wird), das gesamte Wissen über bestimmte Assemblies verloren geht, was dazu führen kann, dass ein Instanz des Modultyps. Das Debugging zeigt, dass die fehlende Assembly in der aktuellen Thread-Assembly-Liste nicht existiert.
Um das zu umgehen, habe ich einen zweiten Check hinzugefügt, der ein wenig dreckig ist, aber durch die DLLs des Verzeichnisses / bin / recursiert und prüft, ob jeder in der Assembly-Liste existiert. Wenn dies nicht der Fall ist, lädt es es mit Assembly.Load und behebt das Kontextproblem dank 'Solving das Assembly Load Context Problem '.
Das würde funktionieren, nur scheint es (und ich bin mir bewusst, dass dies nicht möglich sein sollte) einige Projekte haben immer noch Zugriff auf die fehlende Assembly, zum Beispiel mein eigentliches Webprojekt und nicht das Framework selbst - und es klagt dann dass doppelte Referenzen hinzugefügt wurden!
Hat jemand schon einmal von so etwas gehört oder hat er irgendwelche Ideen, warum eine Assembly bei einer Konfigurationsänderung einfach nicht mehr existiert? Was ist die eleganteste Problemumgehung, um alle Assemblies im Bin neu zu laden? Es muss alles in einem "Hit" sein, so dass die Besucher der Website keinen anderen Unterschied als eine kleine Verzögerung sehen, so dass eine app_offline.htm Datei nicht in Frage kommt. Das Programmatische Umbenennen einer DLL in der Bin und die anschließende Benennung funktioniert zwar, erfordert aber "Ändern" -Berechtigungen für das IIS-Benutzerkonto, was verrückt ist.
Danke für Hinweise, die die Community sammeln kann!
Im Allgemeinen sollten Sie sich nicht darauf verlassen, welche Assemblys derzeit in einer App-Domäne geladen sind, da dies dynamisch geschieht. Rufen Sie stattdessen einfach System.Web.Compilation.BuildManager.GetType () anstelle von Type.GetType () oder Assembly.GetType () auf. Dies sollte nur das Richtige für Sie tun und nicht von Appdomain-Zyklen betroffen sein.
Wie Sie offensichtlich wissen, Es gibt viele Situationen, in denen die aktuelle App-Domäne entladen und neu geladen wird . Nach jedem Neuladen werden alle Assemblies entladen und die gesamte Anwendung wird "von Grund auf neu" gestartet.
Baugruppen werden standardmäßig bei Bedarf geladen. Normalerweise ist dies der Fall, wenn der JIT über eine Referenz stolpert. In der Folge werden die Assemblies in der App-Domäne durch den Appdomain-Reload gelöscht, und sie erscheinen erst später wieder, wenn das JIT sie lädt.
Als Lösung würde ich immer die statische Methode Type.GetType()
verwenden und ein qualifizierter Name der Assembly (z. B. ein Typname mit dem Assemblynamen) Das ist das gleiche, das das Framework verwendet, wenn es Typen lädt, die in der Konfigurationsdatei angegeben sind, und es stellt sicher, dass die benötigte Assembly bei Bedarf durchsucht und geladen wird, ohne irgendwelche Tricks zu verwenden. Siehe den Abschnitt Anmerkungen der obigen Methode (der Methodenname über dem Namen ist ein Link).
Dies erfordert Updates für Ihre Datenbank, damit für die Assembly qualifizierte Namen anstelle von "nur" vollständig qualifizierten Typnamen enthalten sind. Es stellt jedoch auch sicher, dass Sie nicht in Namenskollisionen geraten, wenn zwei Assemblies unterschiedliche Typen mit demselben Namen bereitstellen, also ist das eine gute Idee, denke ich.
Ich habe noch nie von diesem Problem gehört.
Ich bin mir nicht sicher, ob das funktioniert, da ich erst kürzlich darüber gelesen habe, während ich Workarounds für ODAC-Abhängigkeiten untersucht habe, aber die Angabe des Testpfades für Assemblies könnte das Problem beheben.
siehe: Ссылка
Beispiel:
%Vor%Ich habe ein ähnliches Problem, wenn ich 2-5 Dateien, ether web.config, ether andere Dateien und asp.net muss die laufenden Dateien neu erstellen, dann einige Male nicht finden einige Klassen / Funktion, die auf DLL-Dateien, und mein System funktioniert nicht - werfen Sie Fehler wie Ihre.
Meine Lösung ist, dass ich die app_offline.htm auf den root platziere, mache meine Updates, benenne sie um und entferne die app_offline.htm und mein System funktioniert einwandfrei.
Ich bin sicher, dass etwas mit den zwischengespeicherten kompilierten Dateien zu tun hat, aber ich hatte keine genaue Suche was genau das verursacht.
[Was ist die eleganteste Problemumgehung, um alle Baugruppen im Bin neu zu laden]
Nun, was ist die eleganteste Problemumgehung dafür ist, die HttpRuntime.UnloadAppDomain aufzurufen und Ihre Anwendung tatsächlich dazu zu bringen, zu stoppen und erneut zu starten.
Ich weiß nicht, ob dies Ihr Problem löst, Sie müssen Tests machen.
wahrscheinlich auf Global.asax machen so etwas
%Vor%Ich würde versuchen, eine Basisklasse aus der Assembly zu erstellen, die für Sie interessant ist, ohne über Application Start nachzudenken, um sicherzustellen, dass sie geladen ist. Z.B.
%Vor%Das sieht nicht schick aus, aber es ist sehr geradlinig und asp.net sollte alles für Sie tun. Falls Ihre Liste zu dynamisch ist, könnte es etwas wie
sein %Vor%Stellen Sie sicher, dass Sie immer DLL angeben, wenn Sie mit dynaktisch geladenen Klassen arbeiten.
Tags und Links asp.net reflection assemblies