简单注射器 - 注册 ASP.NET 身份
Simple Injector - Registering ASP.NET Identity
我一直在关注这篇文章以尝试获得 ASP.NET Identity 使用 Simple Injector,但我一直 运行 遇到一些问题。
https://github.com/simpleinjector/SimpleInjector/issues/597
我将 SimpleInjectorInitializer
class 设置为如下所示:
public class SimpleInjectorInitializer
{
public static Container Initialize(IAppBuilder app)
{
var container = GetInitializeContainer(app);
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
return container;
}
private static Container GetInitializeContainer(IAppBuilder app)
{
var container = new Container();
//container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.RegisterInstance(app);
container.Register<ApplicationUserManager>();
container.Register(() => 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));
container.Register<SignInManager<ApplicationUser, string>, ApplicationSignInManager>(Lifestyle.Scoped);
container.Register(() => container.IsVerifying ? new OwinContext(new Dictionary<string, object>()).Authentication : HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
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 = 8,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 3;
// 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 it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = app.GetDataProtectionProvider();
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
当我 运行 我的应用出现错误 To be able to use the Lifestyle.Scoped property, please ensure that the container is configured with a default scoped lifestyle by setting the Container.Options.DefaultScopedLifestyle property with the required scoped lifestyle for your type of application.
。
为了解决这个问题,我尝试添加 container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
如果我有那一行,尽管我收到错误:
The configuration is invalid. The following diagnostic warnings were reported:
-[Lifestyle Mismatch] ApplicationSignInManager (Web Request) depends on ApplicationUserManager (Transient).
-[Short Circuited Dependency] AccountController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request).
-[Short Circuited Dependency] ManageController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request).
-[Disposable Transient Component] ApplicationUserManager is registered as transient, but implements IDisposable.
-[Disposable Transient Component] ApplicationSignInManager is registered as transient, but implements IDisposable.
-[Ambiguous Lifestyles] The registration for SignInManager<ApplicationUser, String> (Web Request) maps to the same implementation (ApplicationSignInManager) as the registration for ApplicationSignInManager (Transient) does, but the registration maps to a different lifestyle. This will cause each registration to resolve to a different instance.
-[Ambiguous Lifestyles] The registration for ApplicationSignInManager (Transient) maps to the same implementation (ApplicationSignInManager) as the registration for SignInManager<ApplicationUser, String> (Web Request) does, but the registration maps to a different lifestyle. This will cause each registration to resolve to a different instance.
我不知道下一步该怎么做,如有任何建议,我们将不胜感激。
Simple Injector 给出的错误信息量可能有点多,但您可以将这些信息提炼为两个独立的问题:
ApplicationUserManager
注册为 Transient
- 类型错误地依赖于未注册的类型
ApplicationSignInManager
(瞬态)而不是 SignInManager<ApplicationUser, String>
(Web 请求)。
您当然应该阅读 Diagnostic Services documentation page in the Simple Injector documentation and especially read about Lifestyle Mismatches, Disposable Transient Components and Short-Circuited Dependencies 以了解 Simple Injector 警告的内容以及如何解决问题。
简而言之,修复有两个方面:
- 将
ApplicationUserManager
的注册从 Transient
更改为 Scoped
以防止它的生命周期过短并确保它被处理掉。另请阅读 this part of the documentation 以从 Simple Injector 的上下文中了解 Transient 和 Scoped 之间的区别。
- 确保类型(即
AccountController
和 ManageController
)不依赖于 ApplicationSignInManager
(在它们的构造函数中),而是依赖于它的基类型 SignInManager<ApplicationUser, String>
.
我一直在关注这篇文章以尝试获得 ASP.NET Identity 使用 Simple Injector,但我一直 运行 遇到一些问题。 https://github.com/simpleinjector/SimpleInjector/issues/597
我将 SimpleInjectorInitializer
class 设置为如下所示:
public class SimpleInjectorInitializer
{
public static Container Initialize(IAppBuilder app)
{
var container = GetInitializeContainer(app);
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
return container;
}
private static Container GetInitializeContainer(IAppBuilder app)
{
var container = new Container();
//container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.RegisterInstance(app);
container.Register<ApplicationUserManager>();
container.Register(() => 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));
container.Register<SignInManager<ApplicationUser, string>, ApplicationSignInManager>(Lifestyle.Scoped);
container.Register(() => container.IsVerifying ? new OwinContext(new Dictionary<string, object>()).Authentication : HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
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 = 8,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 3;
// 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 it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = app.GetDataProtectionProvider();
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
当我 运行 我的应用出现错误 To be able to use the Lifestyle.Scoped property, please ensure that the container is configured with a default scoped lifestyle by setting the Container.Options.DefaultScopedLifestyle property with the required scoped lifestyle for your type of application.
。
为了解决这个问题,我尝试添加 container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
如果我有那一行,尽管我收到错误:
The configuration is invalid. The following diagnostic warnings were reported:
-[Lifestyle Mismatch] ApplicationSignInManager (Web Request) depends on ApplicationUserManager (Transient).
-[Short Circuited Dependency] AccountController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request).
-[Short Circuited Dependency] ManageController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request).
-[Disposable Transient Component] ApplicationUserManager is registered as transient, but implements IDisposable.
-[Disposable Transient Component] ApplicationSignInManager is registered as transient, but implements IDisposable.
-[Ambiguous Lifestyles] The registration for SignInManager<ApplicationUser, String> (Web Request) maps to the same implementation (ApplicationSignInManager) as the registration for ApplicationSignInManager (Transient) does, but the registration maps to a different lifestyle. This will cause each registration to resolve to a different instance.
-[Ambiguous Lifestyles] The registration for ApplicationSignInManager (Transient) maps to the same implementation (ApplicationSignInManager) as the registration for SignInManager<ApplicationUser, String> (Web Request) does, but the registration maps to a different lifestyle. This will cause each registration to resolve to a different instance.
我不知道下一步该怎么做,如有任何建议,我们将不胜感激。
Simple Injector 给出的错误信息量可能有点多,但您可以将这些信息提炼为两个独立的问题:
ApplicationUserManager
注册为 Transient- 类型错误地依赖于未注册的类型
ApplicationSignInManager
(瞬态)而不是SignInManager<ApplicationUser, String>
(Web 请求)。
您当然应该阅读 Diagnostic Services documentation page in the Simple Injector documentation and especially read about Lifestyle Mismatches, Disposable Transient Components and Short-Circuited Dependencies 以了解 Simple Injector 警告的内容以及如何解决问题。
简而言之,修复有两个方面:
- 将
ApplicationUserManager
的注册从Transient
更改为Scoped
以防止它的生命周期过短并确保它被处理掉。另请阅读 this part of the documentation 以从 Simple Injector 的上下文中了解 Transient 和 Scoped 之间的区别。 - 确保类型(即
AccountController
和ManageController
)不依赖于ApplicationSignInManager
(在它们的构造函数中),而是依赖于它的基类型SignInManager<ApplicationUser, String>
.