Asp.net mvc 如何使用StructureMap配置ASP.NET Identity ApplicationUserManager

Asp.net mvc 如何使用StructureMap配置ASP.NET Identity ApplicationUserManager,asp.net-mvc,dependency-injection,structuremap,asp.net-identity,asp.net-identity-2,Asp.net Mvc,Dependency Injection,Structuremap,Asp.net Identity,Asp.net Identity 2,我在项目中使用asp.net标识,并将structuremap用作DI框架。问题是当我使用构造函数注入时,ApplicationUserManager没有配置它的所有成员,例如TokenProvider 这是我的ApplicationUserManager类: public class ApplicationUserManager : UserManager<User, long> { public ApplicationUserManager(IUserStore<U

我在项目中使用asp.net标识,并将structuremap用作DI框架。问题是当我使用构造函数注入时,ApplicationUserManager没有配置它的所有成员,例如TokenProvider

这是我的ApplicationUserManager类:

public class ApplicationUserManager : UserManager<User, long>
{
    public ApplicationUserManager(IUserStore<User, long> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new CustomUserStore(context.Get<InsuranceManagementContext>()));

        // Configure the application user manager
        manager.UserValidator = new UserValidator<User, long>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = false
        };

        manager.PasswordValidator = new PasswordValidator
        {
            RequireDigit = true,
            RequiredLength = 8,
            RequireLowercase = false,
            RequireNonLetterOrDigit = true,
            RequireUppercase = false
        };

        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<User, long>(dataProtectionProvider.Create("TEST"));
        }

        return manager;
    }
}
公共类应用程序管理员:用户管理员
{
公共应用程序服务器管理器(IUserStore存储)
:基地(商店)
{
}
公共静态应用程序SerManager创建(IdentityFactoryOptions选项,IOwinContext上下文)
{
var manager=newapplicationUserManager(newcustomuserstore(context.Get());
//配置应用程序用户管理器
manager.UserValidator=新的UserValidator(管理器)
{
AllowOnlyAlphanumericUserNames=false,
RequireUniqueEmail=false
};
manager.PasswordValidator=新密码验证器
{
RequireDigit=true,
所需长度=8,
RequireLowercase=false,
RequiredOnletterDigit=真,
RequireUppercase=false
};
var dataProtectionProvider=options.dataProtectionProvider;
if(dataProtectionProvider!=null)
{
manager.UserTokenProvider=
新的DataProtectorTokenProvider(dataProtectionProvider.Create(“TEST”);
}
退货经理;
}
}
这是Startup.Auth类:

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(InsuranceManagementContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            ExpireTimeSpan = TimeSpan.FromHours(2.0),
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
        });
    }
}
公共部分类启动
{
//有关配置身份验证的详细信息,请访问http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder应用程序)
{
app.CreatePerOwinContext(InsuranceManagementContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
//使应用程序能够使用cookie存储登录用户的信息
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
ExpireTimeSpan=时间跨度从小时(2.0),
AuthenticationMode=Microsoft.Owin.Security.AuthenticationMode.Active,
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/Login”),
});
}
}
这是我的账户管理员:

public class AccountController : BaseController
{
    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }
}
公共类AccountController:BaseController
{
私有应用程序用户管理器\u用户管理器;
公共应用程序管理员用户管理器
{
得到
{
返回_userManager??HttpContext.GetOwinContext().GetUserManager();
}
专用设备
{
_userManager=value;
}
}
公共帐户控制器(ApplicationUserManager用户管理器)
{
UserManager=UserManager;
}
}
我的问题是如何使用structuremap配置ApplicationUserManager? 如果我将其设置为以下代码,它可以工作,但我不知道它是否是一个好的解决方案:

ObjectFactory.Initialize(x =>
{
     ...
     x.For<ApplicationUserManager>().Use(() => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>());
     ...
});
ObjectFactory.Initialize(x=>
{
...
x、 For()。使用(()=>HttpContext.Current.GetOwinContext().GetUserManager());
...
});

请提示我,如果有更好的解决方案,如果它是确定的,那么什么是它的最佳寿命?HttpContextScope、Singleton等?

在为此创建StructureMap配置之前,了解如何手动创建它会有所帮助,也就是说,如果您实际上自己“新建”了所有内容

UserManager依赖于IUserStore,其EntityFramework实现(UserStore)依赖于DbContext。 手动执行所有操作将如下所示:

var dbContext = new IdentityDbContext("Your ConnectionString Name");
var userStore = new UserStore<IdentityUser>(dbContext);
var userManager = new UserManager<IdentityUser>(userStore);
userManager.PasswordValidator = new PasswordValidator
{
    RequiredLength = 6
};
关于配置userManager最复杂的部分与UserTokenProvider(使用数据保护api)有关,如果您手动执行,它将:

var-dataProtectionProvider=新的DpapiDataProtectionProvider(“应用程序名称”);
var dataProtector=dataProtectionProvider.Create(“目的”);
userManager.UserTokenProvider=新的DataProtectorTokenProvider(dataProtector);
下面是StructureMap注册表的一个示例(您可以从这个示例中推断并根据自己的需要调整它):

public DefaultRegistry(){
扫描(
扫描=>{
扫描。卡入总成();
scan.WithDefaultConventions();
使用(新的ControllerConvention())扫描;
});
For()
.Use()
.Ctor()
.Is(cfg=>cfg.SelectConstructor(()=>newidentitydbcontext(“连接字符串”)).Ctor().Is(“IdentitySetupWithStructureMap”);
ForConcreteType()
.配置
.SetProperty(userManager=>userManager.PasswordValidator=新的PasswordValidator
{
所需长度=6
})
.SetProperty(userManager=>userManager.UserValidator=newuservalidator(userManager));
} 

我写了一篇博客,它解释了导致这种配置的过程,还有一个地方,使用这种配置,您可以创建、列出和删除用户。

我刚刚写了一篇关于标识和DI容器的博客:这可能会对您有所帮助。
var dataProtectionProvider = new DpapiDataProtectionProvider("Application name");
var dataProtector = dataProtectionProvider.Create("Purpose");
userManager.UserTokenProvider = new DataProtectorTokenProvider<IdentityUser>(dataProtector);
 public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.With(new ControllerConvention());
            });


        For<IUserStore<IdentityUser>>()
            .Use<UserStore<IdentityUser>>()
            .Ctor<DbContext>()
            .Is<IdentityDbContext>(cfg => cfg.SelectConstructor(() => new IdentityDbContext("connection string")).Ctor<string>().Is("IdentitySetupWithStructureMap"));

        ForConcreteType<UserManager<IdentityUser>>()
            .Configure
            .SetProperty(userManager => userManager.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6
            })
            .SetProperty(userManager => userManager.UserValidator = new UserValidator<IdentityUser>(userManager));                
    }