每次请求都调用ApplicationUserManager.Create

时间:2015-11-17 18:57:43

标签: c# asp.net asp.net-mvc asp.net-identity-2

我使用asp.net mvc 5与外部提供商owin提供(facebook,twitter)

每次请求都会调用ApplicationUserManager.Create。登录用户有很多不必要的东西(密码验证器配置或短信和电子邮件服务配置....)

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
            // Configure validation logic for usernames
            manager.UserValidator = new UserValidator<ApplicationUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = true,
                RequireUniqueEmail = true
            };

            // Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 7,
                RequireNonLetterOrDigit = false,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };
...

此外,我认为这与此

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

我能做些什么来创造&#34;创造&#34;仅在需要时调用。我不想在不需要的时候在那里实例化密码验证器和其他东西

谢谢

2 个答案:

答案 0 :(得分:0)

就个人而言,在这种情况下,绝对不建议使用CreatePerOwinContext。您应该只初始化DbContext,UserManager和SignInManager一次,并让EF和MVC确定何时需要新的上下文。 MVC 5和更新版本更有效地使用依赖注入(DI),从而无需在每个上下文中使用单个实例。

只有当您拥有应被视为关键且需要新上下文的代码时,才应在该特定代码段中执行此操作,而不是在整个站点范围内执行此操作。

答案 1 :(得分:0)

不确定它是否仍然打开,但是......我也不喜欢每次调用ApplicationUserManager的方式,因此我决定将其更改为单例。

自动调用对象的dispose方法,除非您在传入create时传入析构函数回调。

所以我的ApplicationUserManager现在看起来像这样:

public class ApplicationUserManager : UserManager<SmartUser, Guid>
{

    //This manager seems to get re-created on every call! So rather keep a singleton...
    private static ApplicationUserManager _userManager;

    private ApplicationUserManager(IUserStore<SmartUser, Guid> store)
        : base(store)
    {
    }

    internal static void Destroy(IdentityFactoryOptions<ApplicationUserManager> options, ApplicationUserManager manager)
    {
        //We don't ever want to destroy our singleton - so just ignore
    }

    internal static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        if (_userManager == null)
        {
            lock (typeof(ApplicationUserManager))
            {
                if (_userManager == null)
                    _userManager = CreateManager(options, context);
            }
        }

        return _userManager;
    }

    private static ApplicationUserManager CreateManager(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    { 
       ... your existing Create code ...
    }
}

在Startup.Auth中,我传入了Destroy回调

        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create, ApplicationUserManager.Destroy);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

另一种选择是忽略每个请求调用的注册码&#34;并使UserStore成为单身人士......

用这种更加严厉的方法找不到任何缺点......