Я работаю с 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?
Вы пытались использовать PerRequestLifeTimeManager? https://msdn.microsoft.com/en-us/library/microsoft.practices.unity.perrequestlifetimemanager(v=pandp.30).aspx – smoksnes
Сделал так, никакого эффекта, все же введенный UserManager не такой же который создается в Startup.cs, и я не могу понять, где он «потерян». – Thunderer