2014-05-09 9 views
10

In una nuova applicazione ASPNET MVC ora si ottengono i vantaggi di AspIdentity gratuitamente.AspIdentiy ApplicationUserManager è statico, come estendere in modo che partecipi al mio framework IoC?

C'è una piccola linea innocua "inserisci qui il tuo servizio email".

Così ho fatto:

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); 
    } 
} 

e ora la gioia:

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); 
     ... 

come calci Owin in esso chiama il Crea l'ApplicationUserManager in Startup.Auth.cs:

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

e come sto utilizzando AutoFac come contenitore IoC, in global.asa x.cs

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

se il metodo Create è statico in modo da ottenere:
_emailService è nullo

Ho guardato qui: http://forums.asp.net/post/5293670.aspx e How do i create an instance of UserManager e Using Autofac to provide types exported by static factory. ma senza fortuna.

Se cambio:

private My.Services.IEmailService _emailservice; 

per essere pubblico non statico Sento dei IoC scuotendo la testa, e non posso costruire 'riferimento a un oggetto richiesto'

risposta

6

Oggi stavo lottando con la stesso problema (ci sto ancora lavorando da quando sono nuovo ad Asp.Identity). ho fatto in questo modo:

  1. Startup.cs (utilizzare il proprio contenitore)

    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 (ho tolto metodo statico Create):

    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. Controller

    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> { } 
    

questo funziona per me, ma non esitate a suggerire una migliore soluzione.

+0

grazie. Proverò a convertire tra Unity e Autofac. – OzBob

+1

Attualmente il compilatore dà errore: ... il tipo 'ApplicationUser' non può essere utilizzato come parametro di tipo 'TUser' nel tipo generico o nel metodo 'Microsoft.AspNet.Identity.EmailTokenProvider '. Non esiste alcuna conversione implicita dei riferimenti da "ApplicationUser" a "Microsoft.AspNet.Identity.IUser ". Potresti fornire la tua fonte per IdentityModels.cs – OzBob

+0

fatto. fammi sapere se aiuta – free4ride

2

Ho combattuto con questo a lungo oggi, e alla fine, la cosa più semplice da fare era questa.

All'interno del metodo

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

, trovare queste righe di codice.

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

E modificarlo.

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

non mi piace il modello Service Locator, ma tutto il codice MVC su modelli lo usa ed è meglio non combattere il quadro.

0

con Unity, ho aggiunto il testo seguente RegisterTypes(IUnityContainer container) in UnityConfig.cs:

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

Questo prende l'ApplicationUserManager che è stato già creato per l'OwinContext in Startup.ConfigureAuth(IAppBuilder app), e lo rende disponibile per l'iniezione. È possibile mantenere tutto il resto nella sua configurazione predefinita, incluso il metodo statico Create di ApplicationUserManager.

Problemi correlati