dependency-injection - 如何统一注入(inject) ApplicationUserManager

标签 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; }
    }

出于某种原因,我的存储库没有被注入(inject)。 Repository总是 null
我的统一配置中也有这条线
.RegisterType<ApplicationUserManager>(new HierarchicalLifetimeManager())

如何让它注入(inject)?

更新 N :

这是来自我的 Controller 的代码;我是如何得到 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包没有注入(inject) WebApi Controller 。我用过这个method为了注入(inject) WebApi Controller 。我试图删除 Unity.Mvc包但得到Identity抛出错误。据我了解,因为 Unity无法实例化一些 Identity types然而,在设置 Mvc 的情况下,它们正在被配置和工作。容器。
所以我带回了Unity.Mvc包注入(inject)我的Identity types .否则,正如我上面解释的,当 Unity 时,它会在 null refs 上抛出不同的类型。解决Identity types .

所以我的项目中现在有两个容器 Unity.Mvc注入(inject) DependencyResolver.SetResolver(new UnityDependencyResolver(container));需要解决的问题Identity types和定制WebApi注入(inject) config.DependencyResolver = new UnityResolver(container);需要注入(inject)的容器WebApi Controller 都使用相同的 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 澄清了很多事情。

最佳答案

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

首先,如果您使用的是 Entity Framework ,您必须将您的上下文注册到统一。第二次注册其他类型的身份需要它们,如下所示:

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 .

关于dependency-injection - 如何统一注入(inject) ApplicationUserManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32288506/

相关文章:

.net - Unity框架-重用实例

c# - Unity Container 返回单例而不是新实例

c# - Unity 和 WCF 库 : Where to load unity in a wcf library?

c# - EF Code First INSERT 语句与 FOREIGN KEY 约束冲突

asp.net-mvc - SignInManager.PasswordSignInAsync 总是返回失败

c# - 如何使用 DI usinq autofac .net 框架注册 ILogger(Microsoft.Extensions.Logging)

c# - 多接口(interface)装饰器——Autofac 中的循环依赖之谜

Elasticsearch NEST 重用 ElasticClient 进行不同的索引查询

javascript - 自定义图像服务和 native 图像元素构造函数之间的冲突

c# - 使用 ASP.NET Identity 实现权限