2016-03-21 1 views
0

Ich versuche, einen benutzerdefinierten Manager zu erstellen, der in der Steuerung übergeben wird, wenn es aufgerufen wird, und ich habe Probleme, die aktuelle Implementierung des neuen MVC5-Projekts in C# zu verstehen. HierKonstruktor Parameter auf Controller-Aktionen

ist die Standardimplementierung:

public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) 
{ 
    UserManager = userManager; 
    SignInManager = signInManager; 
} 

über all das sind Erklärungen für sie:

public ApplicationSignInManager SignInManager 
{ 
    get 
    { 
     return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
    } 
    private set 
    { 
     _signInManager = value; 
    } 
} 

public ApplicationUserManager UserManager 
{ 
    get 
    { 
     return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    } 
    private set 
    { 
     _userManager = value; 
    } 
} 

nun von meinem Verständnis der SignInManager und Usermanager erstellt werden, wenn Anwendung zum ersten erstellt wird Zeit in Startup.Auth.cs, die wie folgt aussieht:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 

So, jetzt, wenn ich UserManager aufrufen, bekomme ich die erste Instanz, die erstellt wurde, als das Projekt zum ersten Mal ausgeführt wurde.

Ich habe 2 Fragen. Frage 1 ist, was ich oben falsch gesagt habe und habe ich ein falsches Verständnis davon, wie MVC5 funktioniert?

Frage2: Wie werden UserManager und SignInManager im Controller generiert und übergeben? Wo ist der Code, der diese erste Instanz des Managers erstellt und im Controller übergibt? Ich gehe davon aus, dass es app.CreatePerOwnContext that does it ist. Wenn ja, kann ich dann einfach meinen eigenen Manager erstellen und ihn dann auf dieselbe Weise bei Owin registrieren und während des gesamten Projekts wiederverwenden? Erhält mein Code die neuesten Daten aus der Datenbank, wenn ich dies tue und nicht zwischenspeichern?

+1

[Hier ist ein Artikel] (http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/), der Schritt für Schritt zeigt, wie der Service Locator entfernt wird Muster, wenn Sie Dependency Injection verwenden. Wenn Sie DI nicht verwenden, können Sie den Manager nicht an den Controller übergeben, sondern müssen ihn innerhalb des Controllers neu erstellen. – NightOwl888

Antwort

3

Der Code, den Sie zeigen, kommt von der IMO sehr hässlichen MVC5-Vorlage, die aus der Box funktioniert, aber einige hässliche Dinge tut.

Dieser Konstruktor:

public AccountController(ApplicationUserManager userManager, 
     ApplicationSignInManager signInManager) 

macht Sie glauben, OWIN automagically die Manager für Sie einspritzt. Aber das ist nicht der Fall. Aus diesem Grund enthält die Vorlage die hässlichen Eigenschaften, die Sie in den Fragen angegeben haben. Wenn Sie nichts an der Vorlage ändern, wird der Standardkonstruktor aufgerufen (ebenfalls in der Vorlage vorhanden). Um es auszuprobieren, löschen oder kommentieren Sie einfach den Standardkonstruktor und Sie werden sehen, dass AccountController nicht mehr erstellt werden kann.

Also, was tatsächlich passiert ist, dass beide Manager die Service Locator anti pattern in den Getter der gelieferten Eigenschaften befindet verwenden.

Also, wann immer ich UserManager anrufe, bekomme ich die erste Instanz, die erstellt wurde, als das Projekt zum ersten Mal ausgeführt wurde?

Nein, das ist nicht der Fall. Was diese Zeile:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

ist, wird einen Delegierten zu Create Methode beiden Manager zu schaffen. Die Manager werden im Rahmen einer OWIN-Anfrage zwischengespeichert. Bei der nächsten Anfrage werden die Delegierten erneut angerufen und Sie erhalten eine neue ApplicationUserManager usw.

Um ein wenig ausführlicher sein diese Zeile wie folgt umgeschrieben werden:

Func<ApplicationUserManager> userManagerFactory =() => ApplicationUserMangager.Create(); 
app.CreatePerOwinContext<ApplicationUserManager>(userManagerFactory); 

Wenn Sie also hier ein Haltepunkt würde:

public ApplicationUserManager UserManager 
{ 
    get 
    { 
     // place breakpoint here 
     return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    } 
// .... 

Sie sehen würde, dass während sie durch den Code schrittweise, Sie werden die Linie treffen, wo Sie die UserManagerFactory erstellt haben, die wiederum die Create() Methode der ApplicationUserManager anrufen wird.

Wie wird Usermanager und SignInManager erzeugt und in der Steuerung übergeben

Es ist nicht! Sie müssten dazu die Abhängigkeitsinjektion verwenden.

Wenn ja, kann ich dann nur meine eigenen Manager anlegen und dann registrieren Sie es mit Owin in der gleichen Art und Weise und Wiederverwendung während des gesamten Projektes

Ja, Sie können. Sie können den ApplicationUserManager, den Sie auch in der Vorlage "kostenlos" erhalten haben, komplett umgestalten. Solange Sie der Erweiterungsmethode 'CreatePerOwinContext' eine Factory-Methode zur Verfügung stellen.

Wird mein Code die neuesten Daten aus der Datenbank abrufen, wenn ich dies tue und nicht zwischenspeichern? Die Instanzen werden pro Anforderungsbasis zwischengespeichert. So fordern jedes Sie einen neuen bekommen, mit einem neuen DbContext usw.

Ich bin nicht sicher, wie vertraut Sie mit dependency injection aber MVC5 ist eine ziemlich einfache Rahmen damit zu beginnen, IMO.

Ich schrieb einmal eine blogpost, wie ich meinen DI-Container der Wahl (einfacher Injektor) mit der MVC5-Vorlage zu konfigurieren. Ich schrieb auch mehrere Antworten hier auf SO in Bezug auf diese Vorlage: speziell diese one, sollte Sie interessieren. Diese one ist auch interessant!

+0

Ok, das erste Beispiel war definitiv einer der sehr verwirrenden Teile für mich. Ich verstehe, was DI ist. Ich gebe zu, dass ich noch nicht ganz verstehe, warum es nötig ist, aber ich muss noch darüber nachforschen, aber ich weiß, Ninject ist eine sehr populäre Art, dies zu tun. Ich habe versucht herauszufinden, ob OWIN die fraglichen Manager einschleust und wie es aussieht, hat es mich getäuscht, dass es so ist. – Bojan

+0

Sie haben gesagt, dass owin die Delegierten innerhalb der OWIN-Anfrage zwischenspeichert. Was ist die Lebensdauer der Anfrage? Ist es jedes Mal, wenn ich meine Iis recycle? Ist es jedes Mal, wenn eine Seite geladen wird oder ist es pro Benutzer, Login-Sitzung? etc ... – Bojan

+1

Eine OWIN Anfrage ist so lang wie eine normale HTTP Anfrage bevor wir OWIN bekommen haben. –