我一直在研究新版本的ASP.NET Identity 2.1的新功能,其增强之一是集成到OWIN中间件的新的IoC功能。
我在示例中看到的句子之一是这一句:
我在示例中看到的句子之一是这一句:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
这个句子接收一个函数委托,它返回一个在实例中提供的管理器实现的新实例:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
我个人不喜欢这个实现,因为我不能使用容器注入任何依赖,我想为这些经理。
还有一个“IdentityFactoryOptions”和“IOwinContext”是“神奇地”注入到我不能拉出到我的IoC容器的函数。
任何人都有更好的解决方法对这个实现?
解决方法
我从一个开箱即用的MVC5安装开始,并使用AutoFac作为IoC容器。听起来像我试图实现与你类似的目标,让我解释我做了什么。作为免责声明,我对使用IoC和Identity非常新。
我相信IOwinContext是不必要的角色作为一个IoC如果你使用自己的 – 我切换到注册我的ApplicationUserManager与AutoFac。为了实现这一点,我不得不:
从Startup.Auth中删除CreatePerOwinContext行,因为我将在AutoFac中注册ApplicationDbContext和ApplicationUserManager。
//app.CreatePerOwinContext(ApplicationDbContext.Create); //app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
修改ApplicationUserManager构造函数参数,并包含来自Create函数的所有内容。
public ApplicationUserManager(IUserStore<ApplicationUser> store,IdentityFactoryOptions<ApplicationUserManager> options) : base(store) { //all the code from the 'Create' function here,using `this` for `manager` }
将AccountController设置为具有一个构造函数,将一个ApplicationUserManager作为参数,并废弃从OwinContext中获取ApplicationUserManager的UserManager属性。
private ApplicationUserManager _userManager; //every thing that needs the old UserManager property references this now public AccountController(ApplicationUserManager userManager) { _userManager = userManager; }
使用AutoFac注册一切,包括IdentityFactoryOptions的实例。
var x = new ApplicationDbContext(); builder.Register<ApplicationDbContext>(c => x); builder.Register<UserStore<ApplicationUser>>(c => new UserStore<ApplicationUser>(x)).AsImplementedInterfaces(); builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationName") }); builder.RegisterType<ApplicationUserManager>();
这是粗略的总结。我可能错过了一些其他的调整,我不得不做的一路上。