Geben Sie einen expliziten Assemblynamen für den App_Code-Ordner einer dynamisch kompilierten ASP.NET-Website an?

StackOverflow https://stackoverflow.com/questions/9520231

Frage

Kann in einem dynamisch kompilierten ASP.NET-Website-Projekt die Assembly für den App_Code-Ordner explizit benannt werden?

Wenn ich beispielsweise unter normalen Umständen eine ASP.NET-Website betreibe, wird der Assemblyname in generiert Temporary ASP.NET Files\ Der Ordner ist teilweise randomisiert App_Code.neizakfo.dll Wo neizakfo ist der Anteil, der unterschiedlich sein kann.Kann ich explizit einen Namen für die Assembly angeben? App_Code_Web1.dll?

Klärung

Aus geschäftlichen Gründen kann die Website nicht vorkompiliert/bereitgestellt werden.Deshalb suche ich eine Lösung im Kontext Temporary ASP.NET Files Ordner und dynamisch kompilierte Assemblys wie oben erwähnt.


Hintergrund:
Ich bin auf diese Frage gestoßen, als ich nach einer Möglichkeit gesucht habe, eine dynamische Typinstanziierung für eine Klasse im App_Code-Ordner einer Website durchzuführen, indem ich einen durch eine Assembly qualifizierten Namen verwende, der in der Konfiguration gespeichert, aber von der Webseite instanziiert wird, wodurch eine Assemblygrenze überschritten wird.Da die Webseite und der app_code-Code standardmäßig in zwei verschiedene Assemblys kompiliert werden, ist das Standardverhalten der Type.GetType(..)-Methode bei der Suche nach dem Typnamen entweder in der aktuell ausgeführten Assembly (der Webseite) oder in mscorlib nicht der Fall reicht aus, um einen beliebigen Typ aus der App_Code-Assembly auszuwählen.Aufgrund der Randomisierung ist mir nicht bekannt, dass der app_code-Assembly-Name in die für die Assembly qualifizierte Zeichenfolge eingefügt wird.

Ich kann den Datentyp in eine Klassenbibliothek einfügen (da diese einen vordefinierten/genauen Namen hat), um dieses Problem zu beseitigen. Ich würde jedoch gerne wissen, wie man das innerhalb der Website selbst macht, ohne dafür ein Klassenbibliotheksprojekt zu erstellen der Zweck.

War es hilfreich?

Lösung

Sie können dies in einem WebSite-Projekt tun.

Dort ist ein MSDN-Artikel zur Verwendung des Flags -fixednames beim Kompilieren des Projekts.

Dadurch wird effektiv eine Assembly für jede Seite erstellt – default.aspx.dll.Dies ist für Sie jedoch nur unwesentlich nützlicher, da Sie beim Laden immer noch den Namen des gesuchten Steuerelements oder der gesuchten Seite kennen müssen – Sie müssen also sicherstellen, dass Ihre Typen und Benennung konsistent sind.Es sollte jedoch den Namen der Klassen in app_code berücksichtigen, damit dies für Sie funktioniert.

Sie können auch den gesamten Code in app_code in eine eigene Assembly verschieben und diese dann als Projektreferenz hinzufügen.Das würde auch dieses Problem vereinfachen.

Schließlich könnten Sie alle DLLs im bin-Verzeichnis auflisten und jede einzelne nach dem Typ durchsuchen, nach dem Sie suchen.Da dies ziemlich teuer ist, sollten Sie es einmal ausführen und das Ergebnis irgendwo zwischenspeichern, damit Sie es nicht jedes Mal wiederholen müssen, wenn Sie diesen Typ nachschlagen.Dies ist wahrscheinlich die schlechteste Lösung.

Dies ist in einem WebApplication-Projekt trivial, aber ich gehe davon aus, dass Sie beim WebSite-Projekt nicht weiterkommen?

BEARBEITEN: Als Update für die Kommentare;Wenn ich das Publish Web Tool verwende, wird der gesamte Code in app_code im bin-Verzeichnis in einer DLL mit dem Namen App_Code.dll abgelegt. Dieses Verhalten ändert sich auch dann nicht, wenn ich eine feste Benennung verwende (alle festen Benennungen wirken sich auf die Benennung der DLLs aus). jede Seite, Benutzerkontrolle).Wenn ich es benutze ILSpy In dieser Datei kann ich dort meine Kurse sehen.Ich kenne also den Namen der Assembly und ihren Speicherort – ich sollte in der Lage sein, mit minimalem Aufwand an die darin enthaltenen Typen zu gelangen.Ich frage mich, warum ich ein anderes Verhalten als Sie sehe!

Ich habe eine einfache Klasse namens „Person“ mit einer ID und einem Namen erstellt, sie in App_Code eingefügt, die Site kompiliert und dann den folgenden Code ausgeführt:

  Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
  Response.Write(myType.ToString());

Wie erwartet wurde „Person“ geschrieben.

Weitere Bearbeitung

Der Groschen fällt!Wenn ich es dann tue:

  object myObject= Activator.CreateInstance("App_Code.dll", "Person");

Und wenn ich versuche, myObject in eine Person umzuwandeln, erhalte ich die folgende Meldung:

The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll'

Es ist also Zeit, hinterhältig zu sein.

Führen Sie in Global.asax auf Application_OnStart Folgendes aus:

Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));

Auf meiner Test-Standardseite habe ich dann Folgendes getan:

  Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
  Response.Write(app_Code.FullName);

Dadurch erhielt ich den zufällig benannten app_code, mit dem es tatsächlich in temporären ASP.Net-Dateien ausgeführt wird.

Deshalb hasse ich Website-Projekte ;-)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top