2016-05-07 7 views
3

Also habe ich versucht, ASP.NET Identity 2.2.1 einzurichten und ich halte Roadblocks. Um etwas zu sein, das vom Framework automatisch generiert werden soll, scheint es kompliziert zu konfigurieren. Ich denke, ich bin fast da, aber ich habe immer noch Probleme beim Einrichten von IoC mit Simple Injector.Setup Simple Injector mit ASP.NET Identity 2.2.1

Ich habe durch andere StackOverflow Fragen und Blogs zu diesen Themen gelesen. Die meisten von ihnen scheinen veraltet zu sein, weil sie sich mit ASP.NET Identity 1.0 befassen. Es gab sogar genug Änderungen von 2.0 zu 2.2.1 Ich bin auf einige Probleme mit veralteten Lösungen gestoßen. Oder die Lösungen befassen sich mit anderen IoC-Frameworks und ich kann sie einfach nicht in Simple Injector übersetzen. Ich habe andere IoC-Frameworks verwendet, aber ich bin neu in Simple Injector.

UPDATE - Ric .Net's first link in his comment war sehr hilfreich. Ich habe meine Arbeit so umformuliert, dass sie zu seinen Vorschlägen passt, und ich denke, ich bin fast da. Aber ich habe immer noch ein Problem. Ich habe den vorherigen Code mit dem folgenden Code ersetzt.

1) I aktualisiert ApplicationDbContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext(string connectionstring) 
     : base(connectionstring, throwIfV1Schema: false) 
    { 
    } 
} 

2) ich die() -Methode von ApplicationUserManager Erstellen entfernt und bewegt ihn in eine Klasse, die alle meine einfache Injector Code initialisiert :

public static class SimpleInjectorInitializer 
{ 
    public static Container Initialize(IAppBuilder app) 
    { 
     var container = GetInitializeContainer(app); 

     container.Verify(); 

     DependencyResolver.SetResolver(
      new SimpleInjectorDependencyResolver(container)); 

     return container; 
    } 

    public static Container GetInitializeContainer(
       IAppBuilder app) 
    { 
     var container = new Container(); 

     container.RegisterSingle<IAppBuilder>(app); 

     container.RegisterPerWebRequest< 
       ApplicationUserManager>(); 

     container.RegisterPerWebRequest<ApplicationDbContext>(() 
      => new ApplicationDbContext(
      "Your constring goes here")); 

     container.RegisterPerWebRequest<IUserStore< 
      ApplicationUser>>(() => 
      new UserStore<ApplicationUser>(
       container.GetInstance<ApplicationDbContext>())); 

     container.RegisterInitializer<ApplicationUserManager>(
      manager => InitializeUserManager(manager, app)); 

     container.RegisterMvcControllers(
       Assembly.GetExecutingAssembly()); 

     return container; 
    } 

    private static void InitializeUserManager(
     ApplicationUserManager manager, IAppBuilder app) 
    { 
     manager.UserValidator = 
     new UserValidator<ApplicationUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 

     //Configure validation logic for passwords 
     manager.PasswordValidator = new PasswordValidator() 
     { 
      RequiredLength = 6, 
      RequireNonLetterOrDigit = false, 
      RequireDigit = true, 
      RequireLowercase = true, 
      RequireUppercase = true, 
     }; 

     var dataProtectionProvider = 
      app.GetDataProtectionProvider(); 

     if (dataProtectionProvider != null) 
     { 
      manager.UserTokenProvider = 
      new DataProtectorTokenProvider<ApplicationUser>(
       dataProtectionProvider.Create("ASP.NET Identity")); 
     } 
    } 
} 

3) geändert I die Konfigurationsmethode in Startup.cs:

public void Configuration(IAppBuilder app) 
{ 
    var container = SimpleInjectorInitializer.Initialize(app); 
    ConfigureAuth(app, container); 
} 

4) I ConfigureAuth in Configure.Auth.cs aktualisiert:

public void ConfigureAuth(IAppBuilder app, Container container) 
{ 
    // Configure the db context and user manager to use a single instance per request 
    //app.CreatePerOwinContext(ApplicationDbContext.Create); 
    app.CreatePerOwinContext(container.GetInstance<ApplicationUserManager>); 
    // Rest of code here ... 

5) Dann entfernt I der Standardkonstruktor und die UserManager-Eigenschaft von AccountsController.

Das Problem, das ich jetzt habe, ist, dass seit ASP.NET Identity 2.0, sie den Parameter ISecureDataFormat<AuthenticationTicket> accessTokenFormat zum Konstruktor von AccountsController hinzugefügt haben.

public AccountController(ApplicationUserManager userManager, 
    ISecureDataFormat<AuthenticationTicket> accessTokenFormat) 

So, jetzt, wie füge ich DI für ISecureDataFormat<AuthenticationTicket> in der Einfachen Injector?

+2

Lasen Sie [diese] (https://simpleinjector.codeplex.com/Diskussionen/564822) schon? Es diskutiert nicht die "IdentityFactoryOptions", sondern muss einige Hinweise geben. Siehe auch [this] (http://stackoverflow.com/a/28948205/3294832) für eine bessere Methode als die von Ihnen erwähnte Fabrik. –

+1

Hast du [this] gelesen (https: // simeinjector.readthedocs.io/en/latest/LifestyleMismatchatches.html)? Sie sollten die IdentityFactoryOptions als Bereich oder Singleton registrieren. Und nein, es sind nicht Sie, die die besten Vorsätze verletzen; Es ist Identity Feamework mit seiner erstaunlich schlechten Visual Studio Vorlage. – Steven

+1

[Hier ist eine Walkthrough] (http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/), die beschreibt, wie die Standardvorlage MVC 5 für die Integration mit Autofac umgestaltet wird, SimpleInjector oder Unity. – NightOwl888

Antwort

4

Also zwischen der Hilfe Ric .Net (die ich oben als Teil der Frage geschrieben habe) und Lucas Teles answer in another question habe ich endlich meine Antwort bekommen. Lucas schlug das Hinzufügen dieser Zeilen zu meinem Einfachen Injector Setup:

container.Register<ISecureDataFormat<AuthenticationTicket>, 
    SecureDataFormat<AuthenticationTicket>>(Lifestyle.Scoped); 
container.Register<ITextEncoder, Base64UrlTextEncoder>(Lifestyle.Scoped); 
container.Register<IDataSerializer<AuthenticationTicket>, TicketSerializer>(
    Lifestyle.Scoped); 
container.Register<IDataProtector>(
    () => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider() 
     .Create("ASP.NET Identity"), 
    Lifestyle.Scoped); 

meine Behälterbau Methode sieht also nun wie folgt aus:

public static Container GetInitializeContainer(IAppBuilder app) 
{ 
    var container = new Container(); 

    // IoC for ASP.NET Identity 
    container.RegisterSingleton<IAppBuilder>(app); 
    container.Register<ApplicationUserManager>(Lifestyle.Scoped); 
    container.Register<ApplicationDbContext>(
     () => new ApplicationDbContext("Your constring goes here"), 
     Lifestyle.Scoped); 
    container.Register<IUserStore<ApplicationUser>>(
     () => new UserStore<ApplicationUser>(
      container.GetInstance<ApplicationDbContext>()), 
     Lifestyle.Scoped); 
    container.RegisterInitializer<ApplicationUserManager>(
     manager => InitializeUserManager(manager, app)); 
    // Setup for ISecureDataFormat 
    container.Register<ISecureDataFormat<AuthenticationTicket>, 
     SecureDataFormat<AuthenticationTicket>>(Lifestyle.Scoped); 
    container.Register<ITextEncoder, Base64UrlTextEncoder>(Lifestyle.Scoped); 
    container.Register<IDataSerializer<AuthenticationTicket>, 
     TicketSerializer>(Lifestyle.Scoped); 
    container.Register<IDataProtector>(
     () => new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider() 
      .Create("ASP.NET Identity"), 
     Lifestyle.Scoped); 

    // Register all controllers 
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 

    return container; 
} 
+0

Dieser Artikel enthält auch einige gute Hinweise zum 'DataProtectionProvider', der normalerweise von' IdentityFactoryOptions' stammt - http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/ –