2014-05-09 2 views
10

In einer neuen ASPNET MVC-Anwendung erhalten Sie jetzt die AspIdentity Goodies kostenlos.AspIdentiy ApplicationUserManager ist Static, wie zu erweitern, so dass es an meinem IoC-Framework teilnimmt?

Es gibt eine harmlose kleine Linie "schließen Sie Ihren E-Mail-Dienst hier an".

Also habe ich:

public class EmailService : IIdentityMessageService 
{ 
    private static My.Services.IEmailService _emailservice; 

    public EmailService(Insolvency.Services.IEmailService emailservice) 
    { 
     _emailservice = emailservice; 
    } 

    public Task SendAsync(IdentityMessage message) 
    { 
     _emailservice.SendEmail(message); 
     return Task.FromResult(0); 
    } 
} 

und jetzt die Freude:

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    private My.Services.IEmailService _emailservice; 

    public ApplicationUserManager(IUserStore<ApplicationUser> store, My.Services.IEmailService emailservice): base(store)   
    { 
     _emailservice = emailservice; 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()), _emailservice); 
     ... 

als Owin Tritte in ruft die auf ApplicationUserManager erstellen in Startup.Auth.cs:

public partial class Startup 
    { 
    public void ConfigureAuth(IAppBuilder app) 
    { 
     ... 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

und wie ich AutoFac als meine IoC-Container in global.asa verwenden

x.cs
builder.RegisterType<My.Services.EmailService>().As<IEmailService>(); 

wenn die Create-Methode so statisch ist, erhalte ich:
_emailService null ist

ich hier haben gesucht: http://forums.asp.net/post/5293670.aspx und How do i create an instance of UserManager und Using Autofac to provide types exported by static factory. aber kein Glück.

Wenn ich ändern:

private My.Services.IEmailService _emailservice; 

seine Öffentlichkeit nicht-statisch Ich fühle mich IoC Götter schütteln ihre Köpfe, und ich kann nicht ‚Objektverweis erforderlich‘

Antwort

6

Heute baue ich kämpfe mit der gleiches Problem (arbeite noch daran, seit ich neu bei Asp.Identity bin). Ich habe es auf diese Weise:

  1. Startup.cs (Ihre eigenen Container verwenden)

    public class Startup 
    { 
        public void Configuration(IAppBuilder app) 
        { 
         var authConfigurator = new AuthConfigurator(); 
         authConfigurator.ConfigureAuth(app); 
         var unityContainer = UnityConfig<MvcUnityDependencyContainer>.UseContainer(); 
         //Asp identity registration 
         IDataProtectionProvider dataProtectionProvider = app.GetDataProtectionProvider(); 
         unityContainer.RegisterInstance(dataProtectionProvider); 
         unityContainer.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); 
         unityContainer.RegisterType<UserManager<ApplicationUser, int>>(new HierarchicalLifetimeManager()); 
         unityContainer.RegisterType IIdentityMessageService, EmailService>(); 
         unityContainer.RegisterType<IUserStore<ApplicationUser, int>, 
          UserStore<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>>(
          new InjectionConstructor(new ApplicationDbContext())); 
         unityContainer.RegisterType<IIdentityMessageService, EmailService>(); 
        } 
    } 
    
  2. ApplicationUserManager (I statische Methode erstellen entfernt wurde):

    public class ApplicationUserManagerService : UserManager<ApplicationUser, int> 
    { 
        public ApplicationUserManagerService(IUserStore<ApplicationUser, int> store, 
                 IIdentityMessageService emailService, 
                 IDataProtectionProvider dataProtectionProvider) 
                 : base(store) 
        { 
         UserTokenProvider = new EmailTokenProvider<ApplicationUser, int>(); 
         EmailService = emailService; 
         Configure(dataProtectionProvider); 
        } 
        private void Configure(IDataProtectionProvider dataProtectionProvider) 
        { 
         // Configure validation logic for usernames 
         UserValidator = new UserValidator<ApplicationUser, int>(this) 
         { 
          AllowOnlyAlphanumericUserNames = false, 
          RequireUniqueEmail = true 
         }; 
         // Configure validation logic for passwords 
         PasswordValidator = new PasswordValidator 
         { 
          RequiredLength = 1, 
          RequireNonLetterOrDigit = false, 
          RequireDigit = false, 
          RequireLowercase = false, 
          RequireUppercase = false, 
         }; 
         // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user 
         // You can write your own provider and plug in here. 
         RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser, int> 
         { 
          MessageFormat = "Your security code is: {0}" 
         }); 
         RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser, int> 
         { 
          Subject = "Security Code", 
          BodyFormat = "Your security code is: {0}" 
         }); 
         if (dataProtectionProvider != null) 
         { 
          UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity")); 
         } 
        } 
    } 
    
  3. Steuerung

    public class AccountController : Controller 
    { 
        private ApplicationUserManagerService _userManagerService; 
        public AccountController(ApplicationUserManagerService userManagerService) 
        { 
         Contract.Requires(userManagerService != null); 
         _userManagerService = userManagerService; 
        } 
        /*....*/ 
    } 
    
  4. ApplicationUser

    public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim> 
    { 
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager) 
        { 
         var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
         return userIdentity; 
        } 
    } 
    
    public class CustomRole : IdentityRole<int, CustomUserRole> 
    { 
        public CustomRole() { } 
        public CustomRole(string name) { Name = name; } 
    } 
    
    public class CustomUserClaim : IdentityUserClaim<int> { } 
    public class CustomUserLogin : IdentityUserLogin<int> { } 
    public class CustomUserRole : IdentityUserRole<int> { } 
    

Dies funktioniert für mich, aber Sie fühlen sich frei bessere Lösung vorzuschlagen.

+0

danke. Ich werde versuchen, zwischen Unity und Autofac zu konvertieren. – OzBob

+1

Compiler gibt derzeit Fehler: ... der Typ 'ApplicationUser' kann nicht als Typ Parameter 'TUser' im generischen Typ oder Methode 'Microsoft.AspNet.Identity.EmailTokenProvider ' verwendet werden. Es gibt keine implizite Referenzkonvertierung von 'ApplicationUser' zu 'Microsoft.AspNet.Identity.IUser '. Könnten Sie Ihre Quelle für IdentityModels.cs – OzBob

+0

fertig stellen. lass es mich wissen, wenn es hilft – free4ride

2

Ich habe heute lange damit gekämpft, und am Ende war es das Einfachste, das zu tun.

Innerhalb der

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 

Methode, diese Zeilen Code finden.

manager.EmailService = new EmailService(); 
manager.SmsService = new SmsService(); 

Und ändern Sie es zu diesem.

manager.EmailService = new EmailService(DependencyResolver.Current.GetService<Insolvency.Services.IEmailService>()); 

Ich mag nicht das Muster Service Locator, aber alle die MVC Templat-Code verwendet, und es ist am besten, den Rahmen nicht zu kämpfen.

0

mit Unity, habe ich folgende RegisterTypes(IUnityContainer container) in UnityConfig.cs:

container.RegisterType<ApplicationUserManager>(New InjectionFactory(x => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>())); 

Dies nimmt den ApplicationUserManager das war bereits in Startup.ConfigureAuth(IAppBuilder app) für die OwinContext erstellt, und macht es zur Injektion zur Verfügung. Sie können alles andere in seiner Standardkonfiguration beibehalten, einschließlich der statischen Methode Create von ApplicationUserManager.

Verwandte Themen