2009-04-01 7 views
17

Ich erwäge, mit Unity die Lebensdauer einer benutzerdefinierten Benutzerklasseninstanz zu verwalten. Ich plane, den LifetimeManager mit einem benutzerdefinierten ASP.NET-Sitzungsmanager zu erweitern. Ich möchte das aktuell angemeldete Benutzerobjekt aus meinen benutzerdefinierten Klassen speichern und abrufen können und Unity die Instanz von User aus dem Sitzungsobjekt in ASP.NET holen oder (in einem Win32-Projekt) abrufen statisch oder aus dem aktuellen Thread.Verwenden der ASP.NET-Sitzung für die Lebensdauerverwaltung (Unity)

Bis jetzt ist meine beste Lösung, eine statische Instanz meines Unity-Containers beim Start zu erstellen und die Resolve-Methode zu verwenden, um mein Benutzerobjekt aus jeder meiner Klassen abzurufen. Dies scheint jedoch eine Abhängigkeit von dem Einheitscontainer in meinen anderen Klassen zu schaffen. Was ist der Weg der "Einheit", um dieses Ziel zu erreichen? Ich möchte die aktuelle Benutzerinstanz von jeder Klasse lesen/ersetzen können.

+0

Was meinen Sie mit "einem benutzerdefinierten ASP.NET-Sitzungsmanager"? Sprechen Sie über eine NHibernate-Sitzung oder einen Data/ObjectContext? –

Antwort

0

Ich würde denken, dass Sie zwei Dienste benötigen, die Sie durch die Einheit verfügbar machen (oder einen Dienst, der beide Aktionen ausführt).

Anstatt das Benutzerobjekt zu speichern, speichern Sie eine Schnittstellenimplementierung, die eine Methode/Eigenschaft verfügbar macht, die das Benutzerobjekt für Sie abruft. Im ASP.NET-Fall rufen Sie den Benutzer aus der Sitzung ab. In der WinForm-Lösung (oder was auch immer) können Sie es aus dem ausführenden Thread abrufen.

Sie hätten auch eine set-Methode/-Eigenschaft, die Sie verwenden würden, um den Benutzer festzulegen.

+0

Können Sie ein Pseudocode-Beispiel angeben? Ich verstehe nicht, wie Ihre Antwort Unity verwendet oder wie eine einzelne Klasse den Benutzer abrufen kann, ohne zu wissen, ob die Klasse in ASP.NET oder einem WinForm verwendet wird. –

2

Warum verwenden Sie stattdessen das Cache-Objekt nicht ... dann können Sie es von Sieg und Web beide verwenden. Wie folgt aus:

IUnityContainer container= HttpRuntime.Cache.Get("Unity") as IUnityContainer; 

    if (container == null) 
    { 
     container= // init container 

     HttpRuntime.Cache.Add("Unity", 
      container, 
      null, 
      Cache.NoAbsoluteExpiration, 
      Cache.NoSlidingExpiration, 
      CacheItemPriority.NotRemovable, 
      null); 
    } 

    // return container or something 

HttpRuntime.Cache arbeiten beide in Win und Web

-5

Ich entschuldige mich, wenn dies nicht ganz richtig, aber ...

Unity ist ein Spiel dev Plattform, ich daher Angenommen, Sie erstellen eine 3D-App oder ein 3D-Spiel, mit dem Sie etwas Cooles machen möchten (z. B. Multiplayer/Verfolgung von Benutzern mithilfe des Servers).

Warum sich nicht jeder Benutzer anmelden muss, können Sie mit den MembershipProvider- und Formsauthentication-Klassen Zugriff auf die Benutzer-ID/den Benutzernamen erhalten.

Auf Ihrem Server verbinden Sie einfach alle Informationen mit denen für den Benutzer, so dass Sie einfach Daten (einfach Ajax/normale http-Anfrage), die für die Situation/Benutzeranforderung relevant sind, zurückziehen.

Ich weiß das nicht sicher, aber ich glaube, dass Einheit ist etwas, das Client-Seite daher keine Integration mit ihm auf dem Server getan werden muss.

Fragen Sie einfach was Sie brauchen und bearbeiten Sie es auf der Client-Seite.

Auf diese Weise bleiben Sie bei der klassischen n-Tier-Design-Muster, mit dem Sie Ihre Logik von Ihrem Datenspeicher und ui trennen können.

Hope this helps ...

+0

Entschuldigung, aber Ihre Antwort zeigt nur auf einen völlig anderen Weg anstatt eine Lösung für eine sehr knappe Frage zu bieten. – JCallico

+2

Falsche Einheit, überprüfen Sie http://unity.codeplex.com/. Es ist eine Abhängigkeitsinjektions-Bibliothek. – marijne

13

Sie würden die besten Knall mit Unity erhalten, wenn sie mit ASP.Net MVC statt der einfachen alten ASP.Net Projekt verwendet. ASP.Net MVC ermöglicht es Ihnen, einen Container wie Unity zu verwenden, um die Benutzerobjekte, Controller, Modelle usw. zu verwalten. Wenn möglich, verwenden Sie MVC statt ASP.Internet-Formulare für Ihre Projekte.

Wenn ich Ihre Frage richtig verstehe, möchten Sie mit Unity die Lebensdauer des Objekts pro Sitzung beibehalten. Sie müssen einen SessionLifetimeManager implementieren, der LifetimeManager erweitert. Der Code ist ziemlich einfach und geht in diese Richtung:

public class SessionLifetimeManager : LifetimeManager 
{ 
    private string _key = Guid.NewGuid().ToString(); 

    public override object GetValue() 
    { 
      return HttpContext.Current.Session[_key]; 
    } 

    public override void SetValue(object value) 
    { 
      HttpContext.Current.Session[_key] = value; 
    } 

    public override void RemoveValue() 
    { 
      HttpContext.Current.Session.Remove(_key); 
    } 
} 

Sie auch ein ähnliches für PerWebRequest Lebensdauer Management schreiben konnte.

+1

Soweit ich weiß, wird Remove-Methode nie vom Framework aufgerufen. Es ist da, für den Coder. Warum definiert das Framework einen Vertrag und verwendet überhaupt keine der Methoden im Vertrag? Es macht mich verrückt. – Zasz

0

Vielleicht bin ich über das denken, aber ich denke, Sie sollten AoP zusammen mit IoC verwenden. Es ist wirklich eine schöne Paarung. Im Wesentlichen würde ich den Konstruktor der Klassen, die du auflöst, entführen, was sonst als Erstellen eines Aspekts bezeichnet wird. Sie könnten dann den Benutzer bei der Eingabe in den Konstruktor in die Klasse einfügen, aber was auch immer die Klasse auflöst, muss den Benutzer nicht explizit bereitstellen, wodurch eine Paarung mit Unity verhindert wird.

PostSharp ist ein ausgezeichnetes AoP-Framework IMHO.

Jetzt wird Ihre App letztendlich vom AoP-Framework abhängig sein, aber eine vollständig entkoppelte Anwendung kann je nach Ihrer Umgebung unrealistisch sein. Sie werden überrascht sein, wie nützlich die Kombination von AoP und IoC sein kann.

0

Wenn Sie mit "einem benutzerdefinierten ASP.NET-Sitzungsmanager" über eine NHibernate-Sitzung oder einen Data/ObjectContext sprechen, klingt es nach einem IUserRepository, das entweder in den Konstruktor oder in den Property Setter injiziert wird, von dem Sie abrufen können das Benutzerobjekt. Die Implementierung von IUserRepository kann vom Datenbankzugriff bis zum Back-End-Cache usw. reichen. Wenn Sie .Resolve() direkt für den Container verwenden, folgen Sie dem Muster Service Locator und verwenden Unity nicht ordnungsgemäß für alle verfügbaren Funktionen.

Sie können dann Ravi's answer verwenden, um die Lebensdauer des Repositorys zu verwalten.