2010-01-19 11 views
7

Ich habe einen Bibliothekscode, der wissen sollte, ob er im Kontext eines Webservers oder eines eigenständigen Anwendungsservers ausgeführt wird.Wie kann ein .NET-Code wissen, ob er in einer Web-Server-Anwendung ausgeführt wird?

Der offensichtlichste, der in den Sinn kommt, ist der Name der Anwendungskonfigurationsdatei zu überprüfen, und wenn es web.config ist - dann ist dies ein Webserver, ansonsten - eigenständiger Anwendungsserver.

Eine andere Möglichkeit ist, nach etwas wie "Temporäre ASP.NET-Dateien" im Pfad des Schattenordners zu suchen.

Aber ich mag beide nicht, da sie zu hacky und zerbrechlich scheinen. Gibt es eine robuste Möglichkeit, das zu tun, was ich will?

Danke.

P.S.

Man kann eine dedizierte App-Konfiguration festlegen - IsWebServer, aber ich mag es noch mehr.

EDIT:

Während nach einer Lösung für ein anderes Problem suchen, denke ich, ich diese gelöst - die Details here

+0

Warum brauchen Sie den Kontext? –

+0

Wir ordnen dem ersten Ordner im privaten Suchpfad eine besondere Bedeutung zu. Die Sache ist, dass unsere Logik unter dem Webserver etwas anders funktionieren sollte, aufgrund der Unterschiede in privaten Suchpfad-Setups zwischen einem Webserver und einer Standalone-App. – mark

+0

Vielleicht sollten Sie es ausstellen, so dass Sie einfach eine Strategie-Muster-Implementierung in Ihrem Framework speichern würden, so dass das Framework selbst keinen speziellen Code benötigt, sondern der Code in Ihrer Web-Anwendung verbleibt? –

Antwort

8

Um ein anderes Problem zu lösen, fand ich eine gute Lösung für dieses Problem. Es gibt eine private Methode System.Configuration.SettingsPropertyValue.IsHostedInAspnet, die genau das tut, was ich brauche. Als eine private Methode, mag ich nicht, es nennen (obwohl ich Reflektion verwenden könnte), aber die Umsetzung ist trivial:

private bool IsHostedInAspnet() 
{ 
    return (AppDomain.CurrentDomain.GetData(".appDomain") != null); 
} 

(nach Reflector)

Sieht aus wie es ein spezieller Schlüssel ist in die Daten der App-Domäne - ".appDomain", die beim Ausführen im ASP.NET-Webserver festgelegt wird.

Ich werde dabei bleiben.

+0

Ich denke wirklich, das ist schrecklich. Es verwendet ein Implementierungsdetail, das sich ändern kann. Funktioniert es bei Mono? Ich kann mir nicht vorstellen, warum Sie die Konfigurationsoption nicht machen würden. Jeder für sich. –

+0

@NoonSilk Ja, ich habe etwas Googeln gemacht und es scheint, dass ".appDomain" nicht öffentlich dokumentiert ist. Wie bei Mono scheint es, als würde es funktionieren, da der Code explizit einen Wert https://github.com/playscript/playscript-mono/blob/master/mcs/class/System.Web/System.Web.Hosting/ApplicationHost setzt .cs –

7

sind, können Sie für den Check

HttpContext.Current 

Wenn es nicht null, dann wird es von einer Web-App ausgeführt.

Siehe HttpContext.Current Property

+9

Das funktioniert nur, wenn es im selben Thread wie die Anfrage läuft - nachträglich erzeugte Hintergrund-Threads haben keinen HttpContext. –

+0

@DrJokepu - genau. In meinem Fall ist HttpContext.Current null. – mark

2

Sie können die aktuellen Prozessnamen finden Sie:

Process p = Process.GetCurrentProcess(); 
string assemblyName = p.ProcessName; 

und dann prüfen, ob dies die ASP.NET process name

+0

Und wenn es in Mono läuft? –

+0

Ich denke, dass die Antwort die gleiche sein wird. Der Code wird im Kontext des Web-Server-Host-Prozesses ausgeführt. – sagie

6

Die beste Möglichkeit ist, eine Konfigurationseinstellung .

Es ist besser für die Testbarkeit; es ist besser, weil es eine offensichtliche Aussage darüber ist, wie der Code funktioniert, und es ist besser, weil es nicht auf Implementierungsdetails beruht; Sie verzweigen gezielt von einem Wert, den Sie festgelegt haben. Es kann sein, dass die Entscheidung, die Sie treffen, nicht offensichtlich ist und Ihre Variable/Config die Schlussfolgerung nahelegen kann.

Es ist die Option, die ich gehen würde.

+0

Das scheint mir etwas kurzsichtig zu sein. Zum Beispiel möchte ich als Autor einer Komponente, die für die Verwendung durch andere Entwickler vertrieben und verkauft werden kann, dass sich die Lizenzierung für Webprozesse anders verhält als Formulare oder Dienste oder Konsolenanwendungen. Ich möchte nicht, dass der einkaufende Entwickler über die Verwendung der Komponente "lügen" kann, und ich möchte keinen Verweis auf "System.Web", da meine Komponente unter dem .Net-Client-Profil funktioniert. Ich möchte eine Webumgebung erkennen und das Verhalten der Baugruppe intern entsprechend ändern. Ich untersuche gerade, wie man das am besten macht. – BenSwayne

0

Ich denke, das Beste, was zu tun ist, ist die Bibliothek in zwei DLLs zu teilen, eine, die wirklich generisch ist, und eine (die ASP.NET erfordert), die nur auf der Website geladen wird. Überprüfen, ob es derzeit in ASP.NET läuft, fühlt sich an wie ein bisschen wie ein Hack.

Natürlich hängt es von der Situation ab, ob Sie dies leicht tun können oder nicht.

Verwandte Themen