2016-03-10 3 views
0

Я работаю с ASP.NET MVC 5, EF6, ASP.NET Identity и Unity как IoC, и я хочу использовать функциональные возможности, предоставляемые платформой Identity для управления с помощью пользователей и регистрации, поскольку я создаю веб-сайт.Зависимости, которые не вводятся должным образом mvc 5, owin, unity

Startup.cs

public partial class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      ConfigureAuth(app); 
     } 

    public void ConfigureAuth(IAppBuilder app) 
    { 
     // Configure the db context, user manager and signin manager to use a single instance per request 
     app.CreatePerOwinContext(DbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 
     app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create); 



     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Auth/Login"), 
      Provider = new CookieAuthenticationProvider 
      { 
       // Enables the application to validate the security stamp when the user logs in. 
       // This is a security feature which is used when you change a password or add an external login to your account. 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 
      } 
     }); 
    } 



} 

IdentityConfig.cs

public class EmailService : IIdentityMessageService 
    { 
     public async Task SendAsync(IdentityMessage message) 
     { 
      await configSendGridasync(message); 
     } 

    private async Task configSendGridasync(IdentityMessage message) 
    { 
     var myMessage = new SendGridMessage(); 
     myMessage.AddTo(message.Destination); 
     myMessage.From = new System.Net.Mail.MailAddress("[email protected]", "JOhn Smith"); 
     myMessage.Subject = message.Subject; 
     myMessage.Text = message.Body; 
     myMessage.Html = message.Body; 

     var creds = new NetworkCredential("user", "pass"); 

     var transport = new Web(creds); 

     if (transport != null) 
     { 
      await transport.DeliverAsync(myMessage); 
     } 
     else 
     { 
      Trace.TraceError("Failed to create Web transport."); 
      await Task.FromResult(0); 
     } 
    } 
} 


// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. 
public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<DbContext>())); 
     // Configure validation logic for usernames 
     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 = false, 
     }; 

     // Configure user lockout defaults 
     manager.UserLockoutEnabledByDefault = true; 
     manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); 
     manager.MaxFailedAccessAttemptsBeforeLockout = 5; 
     manager.EmailService = new EmailService(); 

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

     } 
     return manager; 
    } 
} 

// Configure the application sign-in manager which is used in this application. 
public class ApplicationSignInManager : SignInManager<ApplicationUser, string> 
{ 
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 
     : base(userManager, authenticationManager) 
    { 
    } 

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) 
    { 
     return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); 
    } 

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) 
    { 
     return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); 
    } 
} 

public class ApplicationRoleManager : RoleManager<IdentityRole> 
{ 
    public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore) 
     : base(roleStore) 
    { 
    } 
    public static ApplicationRoleManager Create(
     IdentityFactoryOptions<ApplicationRoleManager> options, 
     IOwinContext context) 
    { 
     var manager = new ApplicationRoleManager(
      new RoleStore<IdentityRole>(
       context.Get<DbContext>())); 

     return manager; 
    } 
} 

UnityConfig.cs

public class UnityConfig 
    { 
     #region Unity Container 
     private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => 
     { 
      var container = new UnityContainer(); 
      RegisterTypes(container); 
      return container; 
     }); 

    /// <summary> 
    /// Gets the configured Unity container. 
    /// </summary> 
    public static IUnityContainer GetConfiguredContainer() 
    { 
     return container.Value; 
    } 
    #endregion 

    public static void RegisterTypes(IUnityContainer container) 
    { 
     #region AutoMapper DI 
     var config = new MapperConfiguration(cfg => 
     { 
      cfg.AddProfile<AutoMapperWebProfileConfiguration>(); 
     }); 

     var mapper = config.CreateMapper(); 
     container.RegisterInstance(config.CreateMapper()); 

     #endregion 

     #region userManager and roleManager DI 
     var accountInjectionConstructor = new InjectionConstructor(new DbContext()); 
     container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(accountInjectionConstructor); 
     container.RegisterType<IRoleStore<IdentityRole, string>, 
      RoleStore<IdentityRole, string, IdentityUserRole>>(accountInjectionConstructor); 

     #endregion 

     #region AuthenticationManager 
     container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication)); 

     #endregion 
     #region IdentityConfig injects 
     container.RegisterType<DbContext>(); 
     container.RegisterType<ApplicationSignInManager>(); 
     container.RegisterType<ApplicationUserManager>(); 
     container.RegisterType<EmailService>(); 
     container.RegisterType<IMappingEngine>(new InjectionFactory(_ => Mapper.Engine)); 
     #endregion 


    } 
} 

AuthController.cs

public class AuthController : Controller 
{ 

    private IMapper mapper; 
    private RoleManager<IdentityRole> roleManager; 
    private IAuthenticationManager authManager; 
    private ApplicationUserManager userManager; 
    private ApplicationSignInManager signInManager; 

    public AuthController(IMapper mapper, IRoleStore<IdentityRole, string> roleStore, IAuthenticationManager authManager, ApplicationUserManager userManager, ApplicationSignInManager signInManager) 
    { 
     this.mapper = mapper; 
     this.roleManager = new RoleManager<IdentityRole>(roleStore); 
     this.authManager = authManager; 
     this.userManager = userManager; 
     this.signInManager = signInManager; 

    } //rest omitted for brevity. 

Проблема

Когда я запускаю код, все в Startup.cs запускается на выполнение, и все объекты, экземпляры из IdentityConfig.cs, поэтому я получаю экземпляр UserManager который имеет все необходимые свойства (почтовый сервис, userTokenprovider и т. д.), но когда мой контроллер достигнут, добавляется другой объект, который не имеет этих свойств, поэтому я получаю множество исключений (например, IUserTokenProvider не зарегистрирован и т. Д.). Я предполагаю, что UserManager, который вводится в контроллер, является тем, который вводит Unity, а не тем, который создается Startup.cs. Такая же история с остальными частными свойствами, определенными в контроллере. Как я могу сообщить Unity, чтобы использовать объекты, созданные Startup.cs?

+0

Вы пытались использовать PerRequestLifeTimeManager? https://msdn.microsoft.com/en-us/library/microsoft.practices.unity.perrequestlifetimemanager(v=pandp.30).aspx – smoksnes

+0

Сделал так, никакого эффекта, все же введенный UserManager не такой же который создается в Startup.cs, и я не могу понять, где он «потерян». – Thunderer

ответ

2

Очевидно, что OWIN и Unity создают собственные идентификационные объекты в вашем коде, поэтому в зависимости от использования вы получите другой объект. Чтобы этого избежать, вы должны решить, какой из них ответственен за создание вашего объекта, OWIN или Unity. Так как рекомендуется, чтобы позволить DI сделать такую ​​вещь было бы гораздо лучше, чтобы изменить свой старт до файла, как это:

public void ConfigureAuth(IAppBuilder app) 
{ 
    app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>()); 
    app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>()); 
    // other configs 
} 

Теперь Owin получает те же объекты единства. Но вам также нужна дополнительная настройка и учет для интеграции Unity с Identity. I've already answered this смотрите.

+0

статья действительно помогла мне решить любые вопросы или проблемы! – Thunderer

Смежные вопросы