如何统一注入 ApplicationUserManager [英] How to inject ApplicationUserManager with unity

查看:22
本文介绍了如何统一注入 ApplicationUserManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 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

For some reason my repository in not getting injected. Repository is always null

我的统一配置中也有这一行

I also have this line in my unity configuration

.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager())

如何让它注入?

更新 N:

这是来自我的控制器的代码;我如何获得 UserManager:

This is code from my controller; How I am getting 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 时,它会在 null refs 上抛出不同类型.

As I find out Unity.Mvc package is not injecting WebApi controllers. I used this method in order to inject WebApi controllers. I was trying to remove Unity.Mvc package but got Identity throwing errors. From my understanding because Unity was not able to instantiate some Identity types however they were being configured and worked in the case of setting Mvc container. So I brought back the Unity.Mvc package to inject my Identity types. Otherwise, as I explained above, it is throwing different kind on null refs when Unity resolving Identity types.

所以我的项目中现在有两个容器 Unity.Mvc injection DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 需要解析 Identity 类型 和自定义 WebApi 注入 config.DependencyResolver = new UnityResolver(container); 需要使用相同 UnityConfig 注入 WebApi 控制器的容器.

So I have two containers now in my project Unity.Mvc injection DependencyResolver.SetResolver(new UnityDependencyResolver(container)); that needed to resolve Identity types and custom WebApi injection config.DependencyResolver = new UnityResolver(container); container that needed to inject WebApi contorllers both using same UnityConfig.

更新 3:

我变了这个:

app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());

到这里

app.CreatePerOwinContext(() => UnityConfig.GetConfiguredContainer().Resolve<ApplicationUserManager>());

Startup.ConfigureAuth() 中,现在我的 WebApi 容器完全正常工作并构建了所有必需的 Identity types,因此我可以禁用 Mvc 容器,甚至可以完全删除 <代码>Unity.Mvc 包.

in Startup.ConfigureAuth() and now I my WebApi container is fully working and constructing all required Identity types so I can disable Mvc container or even completely can remove Unity.Mvc package.

感谢@Sam Farajpour Ghamari 澄清了很多事情.

Thanks to @Sam Farajpour Ghamari for clerifying lots of things.

推荐答案

因为您将 UserManager 与 OWIN 一起使用.您需要将 OWIN 容器与 unity 集成.因为我没有看到你的其他部分代码,特别是 OWIN 启动方法.我展示了一个简单的例子来演示如何自己做到这一点.

Since you are using UserManager with OWIN. You need to integrate OWIN container with unity. Where as I don't see your other part of codes specially OWIN startup method. I show a simple example to demonstrate how you can do this by own.

首先,如果您使用实体框架,您必须将您的上下文注册为统一.第二个注册身份需要它们的其他类型,如下所示:

First if you are using Entity Framework you must register your context to unity. Second register other type which Identity need them like this:

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的构造函数:

Then change constructor of ApplicationUserManager like this:

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() 方法中更改以下几行:

Now in your Startup.ConfigureAuth() method change following lines:

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 负责创建我们的类现在.

Also we don't need ApplicationUserManager Create() and ApplicationSignInManager.Create() methods anymore and we could easily remove them, since Unity takes responsibility of create our classes now.

现在我们将 Identity 与 unity 完全集成.如需更多复杂信息,我强烈建议您阅读这篇很棒的博文.

Now we fully integrate Identity with unity. For further and complex information I deeply encourage you to read this awesome blog post.

这篇关于如何统一注入 ApplicationUserManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆