sre*_*moh 8 dependency-injection unity-container asp.net-identity asp.net-web-api2
我这样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; }
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我的存储库没有被注入.Repository总是null
我的统一配置中也有这一行
.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager())
Run Code Online (Sandbox Code Playgroud)
如何注射?
更新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(...);
}
Run Code Online (Sandbox Code Playgroud)
我当前的统一配置
.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>()
Run Code Online (Sandbox Code Playgroud)
更新N + 1:
正如我发现Unity.Mvc包不是注入WebApi控制器.我使用这种方法来注入WebApi控制器.我试图删除Unity.Mvc包但Identity丢失错误.从我的理解,因为Unity无法实例化一些,Identity types但他们正在配置和工作在设置Mvc容器的情况下.所以我带回来Unity.Mvc给我注射Identity types.否则,正如我上面解释的那样,在Unity解析时它会在null refs上抛出不同的类型Identity types.
所以我现在在我的项目Unity.Mvc注入DependencyResolver.SetResolver(new UnityDependencyResolver(container));中有两个容器需要解析Identity types和自定义WebApi注入config.DependencyResolver = new UnityResolver(container);容器,需要WebApi使用相同的UnityConfig 注入控制器.
更新3:
我改变了这个:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
Run Code Online (Sandbox Code Playgroud)
对此
app.CreatePerOwinContext(() => UnityConfig.GetConfiguredContainer().Resolve<ApplicationUserManager>());
Run Code Online (Sandbox Code Playgroud)
在Startup.ConfigureAuth()现在我的WebApi容器完全正常工作并构建所有必需的Identity types所以我可以禁用Mvc容器甚至完全可以删除Unity.Mvc包.
感谢@Sam Farajpour Ghamari对许多事情的批判.
Sam*_*ari 21
因为你正在使用UserManagerOWIN.您需要将OWIN容器与统一集成.在哪里我没有看到你的代码的其他部分特别是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());
Run Code Online (Sandbox Code Playgroud)
然后改变这样的构造函数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
}
Run Code Online (Sandbox Code Playgroud)
现在在您的Startup.ConfigureAuth()方法中更改以下行:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(EFDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// others
}
Run Code Online (Sandbox Code Playgroud)
至:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
// other configs
}
Run Code Online (Sandbox Code Playgroud)
此外,我们不再需要ApplicationUserManager Create()和ApplicationSignInManager.Create()方法,我们可以轻松删除它们,因为Unity现在负责创建我们的类.
现在我们将身份与统一完全融合.对于更复杂的信息,我非常鼓励您阅读这篇精彩的博文.