Wie kann ich ein robustes Session-per-Anfragemuster in meinem Projekt implementieren, während auf Information Hiding konzentrieren?

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

Frage

Ich bin derzeit ein ASP.NET MVC-Projekt erstellen, mit NHibernate als persistance Schicht.

Für jetzt haben einige Funktionen implementiert worden, aber nur mit lokalen NHibernate Sitzungen: jede Methode, die die Datenbank zugegriffen wird (Lesen oder Schreiben) benötigt eine eigene NHibernate Sitzung instanziiert, mit der „mit ()“ Klausel

Das Problem ist, dass ich nutzen möchten NHibernate faul-Laden Fähigkeiten die Leistung meines Projekts zu verbessern.

Dies bedeutet eine offene NHibernate Sitzung pro Anfrage, bis die Ansicht gerendert wird. Darüber hinaus müssen gleichzeitige Anfragen unterstützt (die gleichzeitig mehrere Sitzungen) werden.

Wie kann ich das so sauber wie möglich erreichen?

Ich suchte im Internet ein wenig und über die Sitzung-pro-Anfragemuster gelernt. Die meisten der Implementierungen sah ich eine Art von Http * (Httpcontext, etc.) Objekt zum Speichern der Sitzung verwendet. Außerdem wird die Application_BeginRequest / Application_EndRequest Funktionen kompliziert, da sie für jede HTTP-Anforderung (aspx-Dateien, CSS-Dateien, js Dateien, etc.) gefeuert werden, wenn ich nur eine Sitzung einmal pro Anforderung instanziiert werden soll.

Die Sorge, dass ich habe, ist, dass ich will nicht meine Ansichten oder Controller Zugriff auf NHibernate-Sitzungen (oder, allgemeiner, NHibernate Namespaces und Code). Das bedeutet, dass ich will nicht zu Griff Sitzungen auf Controller-Ebene noch die Ansicht ein.

ich ein paar Optionen im Sinn haben. Welches scheint die beste?

  • Verwenden Sie Abfangjäger (wie in GRAILS), die vor und nach der Controller-Aktion ausgelöst werden. Diese würden öffnen und zu schließen Sessions / Transaktionen. Ist dies möglich, in der ASP.NET MVC Welt?
  • Verwenden Sie die CurrentSessionContext Singleton zur Verfügung gestellt von NHibernate in einem Web-Kontext. Mit Diese Seite als Beispiel, ich glaube, das ist ziemlich viel versprechend, aber das erfordert noch Filter auf Controller-Ebene.
  • Verwenden Sie die HttpContext.Current.Items die Anforderung Sitzung zu speichern. Dies, gepaart mit ein paar Zeilen Code in Global.asax.cs kann mich leicht schaffen, mit einer Sitzung auf Antrag Ebene. Allerdings bedeutet dies, dass Abhängigkeiten zwischen NHibernate und meinen Ansichten injiziert werden (Httpcontext).

Vielen Dank!

War es hilfreich?

Lösung

Nun Jungs, nach ein paar Tagen Arbeit, entschied ich mich schließlich zu verwenden, die HttpContext.Current.Items die Sitzung zu laden.

Es funktioniert super!

Hier ist, wie ich es tat

import System.Web
class SessionManager {
    public static ISession GetSession()
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session == null) {
            session = ...; // Create session, like SessionFactory.createSession()...
            HttpContext.Current.Items.Add("NHibernateSession", session);
        }
        return session;
    }

    public static void CloseSession()
    {
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session != null) {
            if (session.IsOpen) {
                session.close();
            }
            HttpContext.Current.Items.Remove("NHibernateSession");
        }
    }
}

Durch die statischen Methoden unter Verwendung von dieser Klasse zur Verfügung gestellt, kann man eine Sitzung (zum Beispiel in einem Controller) erhalten, der mit dem Strom verbunden ist Httpcontext (die aktuelle Web-Anfrage). Wir brauchen einen anderen Code-Snippet die Close () -Methode aufrufen, wenn die Anforderung abgeschlossen ist.

In Global.asax.cs:

protected void Application_EndRequest(object sender, EventArgs args)
{
    NHibernateSessionManager.CloseSession();
}

Das Application_EndRequest Ereignis wird automatisch aufgerufen, wenn die Sitzung beendet ist, so dass die Sitzung ordnungsgemäß eine entsorgt geschlossen werden kann. Dies ist nützlich, denn sonst würden wir dies nicht in jedem Regler zu tun haben!

Andere Tipps

Mit DI zusammen mit einem IoC. Die meisten IOCs kommen mit einem Pro-Anfrage Instanziierungsverhalten.

Meine „Lösung“ beinhaltet Unity mit Sitzung pro Anfrage zu injizieren in Controller:

http://letsfollowtheyellowbrickroad.blogspot.com /2010/05/nhibernate-sessions-in-aspnet-mvc.html

Hier finden Sie aktuelle S # arp Architektur . Es ist eine sehr schöne Architektur für ASP.NET MVC und NHibernate.

Sie können eine Aktion Filter hinzufügen, die Ihre NHibernate Sitzung und Transaktionen verwalten. (Dies kann bei der Aktion oder Controller-Ebene durchgeführt werden.) Hier ist ein Beispiel dafür ist:

http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx

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