【问题标题】:How to inject ApplicationUserManager with unity如何统一注入 ApplicationUserManager
【发布时间】:2015-11-24 03:29:48
【问题描述】:

我有这样定义的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 injection DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 需要解析Identity types 和自定义WebApi injection config.DependencyResolver = new UnityResolver(container); 容器需要注入WebApi contorllers 都使用相同的UnityConfig。

更新 3:

我变了 这个:

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

到这里

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

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

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

【问题讨论】:

  • 你如何访问ApplicationUserManager对象实例?
  • @SamFarajpourGhamari 是的,我可以进入调试我的自定义 CreateAsync() 方法。但是Repository 没有注入,等于null
  • 你是通过调用HttpContext.GetOwinContext().Get&lt;ApplicationSignInManager&gt;()方法得到对象的实例吗?
  • @SamFarajpourGhamari 尝试调用 var temt = HttpContext.Current.GetOwinContext(); 但收到错误“在上下文中找不到 owin.Environment 项。”
  • 我想知道您如何获得 ApplicationUserManager 本身的实例。可以提交相关代码吗?

标签: dependency-injection unity-container asp.net-identity asp.net-web-api2


【解决方案1】:

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

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

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

现在我们将身份与统一完全整合在一起。对于更多和复杂的信息,我强烈建议您阅读this awesome blog post

【讨论】:

  • 我正在像这样创建ApplicationUserManagervar manager = new ApplicationUserManager(new CustomUserStore(context.Get&lt;ApplicationDbContext&gt;())); - 这是来自IdentityConfig.cs 的代码。如果我像你上面说的那样改变构造方法,它会如何改变它?
  • 您是在静态ApplicationUserManager.Create() 方法中创建用户管理器吗?
  • 因为我们想要 Unity 创建用户管理器,实际上我们不再需要 ApplicationUserManager.Create() 方法了。只需将您的配置从该方法复制到构造函数 ApplicationUserManager 除了 var manager = new ApplicationUserManager(new CustomUserStore(context.Get&lt;ApplicationDbContext&gt;())); 行,因为现在没用了
  • 是的,它是在ApplicationUserManager.Create()中创建的
  • app.CreatePerOwinContext(() =&gt; DependencyResolver.Current.GetService&lt;ApplicationUserManager&gt;()); 给我空引用例外
猜你喜欢
  • 1970-01-01
  • 2017-01-09
  • 2017-11-28
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多