简体   繁体   English

简单注入器 - 注册 ASP.NET 身份

[英]Simple Injector - Registering ASP.NET Identity

I've been following this article to try and get ASP.NET Identity working with Simple Injector, but I've been running into some issues.我一直在关注这篇文章,试图让 ASP.NET Identity 与 Simple Injector 一起工作,但我遇到了一些问题。 https://github.com/simpleinjector/SimpleInjector/issues/597 https://github.com/simpleinjector/SimpleInjector/issues/597

I setup my SimpleInjectorInitializer class to look like this:我将SimpleInjectorInitializer类设置为如下所示:

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

When I run my app I get the error 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.当我运行我的应用程序时,我收到错误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. . .

To fix this, I tried adding container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();为了解决这个问题,我尝试添加container.Options.DefaultScopedLifestyle = new WebRequestLifestyle(); If I have that line though I get the error:如果我有那条线,虽然我收到错误:

The configuration is invalid.配置无效。 The following diagnostic warnings were reported:报告了以下诊断警告:

-[Lifestyle Mismatch] ApplicationSignInManager (Web Request) depends on ApplicationUserManager (Transient). -[生活方式不匹配] ApplicationSignInManager (Web Request) 依赖于 ApplicationUserManager (Transient)。

-[Short Circuited Dependency] AccountController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request). -[短路依赖] AccountController 可能错误地依赖于未注册类型 ApplicationSignInManager (Transient) 而不是 SignInManager<ApplicationUser, String> (Web Request)。

-[Short Circuited Dependency] ManageController might incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request). -[短路依赖] ManageController 可能错误地依赖于未注册类型 ApplicationSignInManager (Transient) 而不是 SignInManager<ApplicationUser, String> (Web Request)。

-[Disposable Transient Component] ApplicationUserManager is registered as transient, but implements IDisposable. -[Disposable Transient Component] ApplicationUserManager 注册为瞬态,但实现了 IDisposable。

-[Disposable Transient Component] ApplicationSignInManager is registered as transient, but implements IDisposable. -[Disposable Transient Component] ApplicationSignInManager 注册为瞬态,但实现了 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. -[模糊的生活方式] SignInManager<ApplicationUser, String>(Web 请求)的注册映射到与 ApplicationSignInManager(瞬态)的注册相同的实现 (ApplicationSignInManager),但注册映射到不同的生活方式。 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. -[模糊的生活方式] ApplicationSignInManager(瞬态)的注册映射到与 SignInManager<ApplicationUser, String>(Web 请求)的注册相同的实现 (ApplicationSignInManager),但注册映射到不同的生活方式。 This will cause each registration to resolve to a different instance.这将导致每个注册解析为不同的实例。

I'm at a loss of what to do next, any suggestions would be appreciated.我不知道下一步该做什么,任何建议将不胜感激。

The amount of error information given by Simple Injector can be a bit overwhelming, but you can distill the information down to two separate problems: Simple Injector 给出的错误信息量可能有点多,但您可以将信息提炼为两个单独的问题:

  • ApplicationUserManager is registered as Transient ApplicationUserManager注册为 Transient
  • Types incorrectly depend on unregistered type ApplicationSignInManager (Transient) instead of SignInManager<ApplicationUser, String> (Web Request).类型错误地依赖于未注册的类型ApplicationSignInManager (Transient) 而不是SignInManager<ApplicationUser, String> (Web Request)。

You should certainly read the Diagnostic Services documentation page in the Simple Injector documentation and especially read about Lifestyle Mismatches , Disposable Transient Components and Short-Circuited Dependencies to understand what Simple Injector is warning about and how to fix the problem.您当然应该阅读 Simple Injector 文档中的诊断服务文档页面,尤其是阅读Lifestyle MismatchesDisposable Transient ComponentsShort-Circuited Dependencies以了解 Simple Injector 警告的内容以及如何解决问题。

In short, the fix is two-fold:简而言之,修复有两个方面:

  1. Change the registration of ApplicationUserManager from Transient to Scoped to prevent it from having a too-short lifetime and to ensure it is disposed of.ApplicationUserManager的注册从Transient更改为Scoped以防止它的生命周期太短并确保它被处理掉。 Also read this part of the documentation to learn the difference between Transient and Scoped from the context of Simple Injector.另请阅读文档的这一部分,以从 Simple Injector 的上下文中了解 Transient 和 Scoped 之间的区别。
  2. Make sure that types (ie AccountController and ManageController ) don't depend on ApplicationSignInManager (in their constructor), but instead depend on its base type SignInManager<ApplicationUser, String> .确保类型(即AccountControllerManageController )不依赖于ApplicationSignInManager (在它们的构造函数中),而是依赖于其基本类型SignInManager<ApplicationUser, String>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM