如何统一注入ApplicationUserManager
How to inject ApplicationUserManager with unity
我 ApplicationUserManager
定义如下:
public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
: base(store)
{
}
public override Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
{
var result = base.CreateAsync(user, password);
//...
Repository.DoSomething(...); //Repository is null here
//..
}
[Dependency]
public IRepository Repository { get; set; }
}
出于某种原因,我的存储库没有被注入。 Repository
总是 null
我的统一配置中也有这一行
.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager())
如何注入?
更新 N:
这是来自我的控制器的代码;我如何获得 UserManager
:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
//calling my implemintation
IdentityResult result = await UserManager.CreateAsync(...);
}
我当前的统一配置
.RegisterType<IUserStore<ApplicationUser, int>, CustomUserStore>(new HierarchicalLifetimeManager())
.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication))
.RegisterType<UserManager<ApplicationUser, int>, ApplicationUserManager>()
.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<AccountController>(new InjectionConstructor())
.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<ApplicationUserManager>()
更新 N+1:
我发现 Unity.Mvc
包没有注入 WebApi 控制器。我使用这个 method 来注入 WebApi 控制器。我试图删除 Unity.Mvc
包但得到 Identity
抛出错误。根据我的理解,因为 Unity
无法实例化一些 Identity types
但是它们在设置 Mvc
容器的情况下被配置和工作。
所以我带回 Unity.Mvc
包来注入我的 Identity types
。否则,正如我上面所解释的,当 Unity
解析 Identity types
.
时,它会在空引用上抛出不同的类型
所以我的项目中现在有两个容器 Unity.Mvc
注入 DependencyResolver.SetResolver(new UnityDependencyResolver(container));
需要解析 Identity types
和自定义 WebApi
注入 config.DependencyResolver = new UnityResolver(container);
需要的容器使用相同的 UnityConfig 注入 WebApi
contorllers。
更新 3:
我变了
这个:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
至此
app.CreatePerOwinContext(() => UnityConfig.GetConfiguredContainer().Resolve<ApplicationUserManager>());
在 Startup.ConfigureAuth()
中,现在我的 WebApi 容器完全正常工作并构建了所有必需的 Identity types
所以我可以禁用 Mvc 容器,甚至可以完全删除 Unity.Mvc
包。
感谢@Sam Farajpour Ghamari 澄清了很多事情。
因为您将 UserManager
与 OWIN 一起使用。您需要将 OWIN 容器与 unity 集成。因为我没有看到你的代码的其他部分,特别是 OWIN 启动方法。我展示了一个简单的示例来演示如何自己执行此操作。
首先,如果您使用 Entity Framework,您必须将您的上下文注册到 unity。第二个注册身份需要它们的其他类型是这样的:
container.RegisterType<DbContext, MyDbContext>(new PerRequestLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>,
UserStore<ApplicationUser>>(new PerRequestLifetimeManager());
container.RegisterType<ApplicationUserManager>(new PerRequestLifetimeManager());
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication))
container.RegisterType<ApplicationSignInManager>(new PerRequestLifetimeManager());
然后像这样更改 ApplicationUserManager
的构造函数:
public ApplicationUserManager(IUserStore<ApplicationUser> store,
IRepository repo)
: base(store)
{
this.Repository=repo;
// put your other configuration here instead of putting in
// static ApplicationUserManagerCreate() method.
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
this.UserLockoutEnabledByDefault = true;
this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
this.MaxFailedAccessAttemptsBeforeLockout = 5;
// and your other configurations
}
现在在您的 Startup.ConfigureAuth()
方法中更改以下行:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(EFDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// others
}
至:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
// other configs
}
此外,我们不再需要 ApplicationUserManager Create()
和 ApplicationSignInManager.Create()
方法,我们可以轻松删除它们,因为 Unity 现在负责创建我们的 类。
现在我们将 Identity 与 unity 完全结合起来。对于更多和复杂的信息,我强烈建议您阅读 this awesome blog post。
我 ApplicationUserManager
定义如下:
public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
: base(store)
{
}
public override Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
{
var result = base.CreateAsync(user, password);
//...
Repository.DoSomething(...); //Repository is null here
//..
}
[Dependency]
public IRepository Repository { get; set; }
}
出于某种原因,我的存储库没有被注入。 Repository
总是 null
我的统一配置中也有这一行
.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager())
如何注入?
更新 N:
这是来自我的控制器的代码;我如何获得 UserManager
:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
//calling my implemintation
IdentityResult result = await UserManager.CreateAsync(...);
}
我当前的统一配置
.RegisterType<IUserStore<ApplicationUser, int>, CustomUserStore>(new HierarchicalLifetimeManager())
.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication))
.RegisterType<UserManager<ApplicationUser, int>, ApplicationUserManager>()
.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<AccountController>(new InjectionConstructor())
.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager())
.RegisterType<ApplicationUserManager>()
更新 N+1:
我发现 Unity.Mvc
包没有注入 WebApi 控制器。我使用这个 method 来注入 WebApi 控制器。我试图删除 Unity.Mvc
包但得到 Identity
抛出错误。根据我的理解,因为 Unity
无法实例化一些 Identity types
但是它们在设置 Mvc
容器的情况下被配置和工作。
所以我带回 Unity.Mvc
包来注入我的 Identity types
。否则,正如我上面所解释的,当 Unity
解析 Identity types
.
所以我的项目中现在有两个容器 Unity.Mvc
注入 DependencyResolver.SetResolver(new UnityDependencyResolver(container));
需要解析 Identity types
和自定义 WebApi
注入 config.DependencyResolver = new UnityResolver(container);
需要的容器使用相同的 UnityConfig 注入 WebApi
contorllers。
更新 3:
我变了 这个:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
至此
app.CreatePerOwinContext(() => UnityConfig.GetConfiguredContainer().Resolve<ApplicationUserManager>());
在 Startup.ConfigureAuth()
中,现在我的 WebApi 容器完全正常工作并构建了所有必需的 Identity types
所以我可以禁用 Mvc 容器,甚至可以完全删除 Unity.Mvc
包。
感谢@Sam Farajpour Ghamari 澄清了很多事情。
因为您将 UserManager
与 OWIN 一起使用。您需要将 OWIN 容器与 unity 集成。因为我没有看到你的代码的其他部分,特别是 OWIN 启动方法。我展示了一个简单的示例来演示如何自己执行此操作。
首先,如果您使用 Entity Framework,您必须将您的上下文注册到 unity。第二个注册身份需要它们的其他类型是这样的:
container.RegisterType<DbContext, MyDbContext>(new PerRequestLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>,
UserStore<ApplicationUser>>(new PerRequestLifetimeManager());
container.RegisterType<ApplicationUserManager>(new PerRequestLifetimeManager());
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication))
container.RegisterType<ApplicationSignInManager>(new PerRequestLifetimeManager());
然后像这样更改 ApplicationUserManager
的构造函数:
public ApplicationUserManager(IUserStore<ApplicationUser> store,
IRepository repo)
: base(store)
{
this.Repository=repo;
// put your other configuration here instead of putting in
// static ApplicationUserManagerCreate() method.
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
this.UserLockoutEnabledByDefault = true;
this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
this.MaxFailedAccessAttemptsBeforeLockout = 5;
// and your other configurations
}
现在在您的 Startup.ConfigureAuth()
方法中更改以下行:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(EFDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// others
}
至:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
// other configs
}
此外,我们不再需要 ApplicationUserManager Create()
和 ApplicationSignInManager.Create()
方法,我们可以轻松删除它们,因为 Unity 现在负责创建我们的 类。
现在我们将 Identity 与 unity 完全结合起来。对于更多和复杂的信息,我强烈建议您阅读 this awesome blog post。