DI如何在ASP.NET Core 1中的多个源中进行选择

时间:2016-02-26 03:16:24

标签: c# asp.net-mvc dependency-injection

在ASP.NET Core 1中,使用AddScoped()在ConfigureServices()中添加了一些其他服务。

其中一项增加的服务是“MyUserManager”,它继承自内置的UserManager。

调试堆栈跟踪显示默认的UserClaimsPrincipalFactory使用默认的UserManager而不是MyUserManager。查看UserClaimsPrincipalFactory的构造函数:

public UserClaimsPrincipalFactory(
    UserManager<TUser> userManager, 
    RoleManager<TRole> roleManager, 
    IOptions<IdentityOptions> optionsAccessor)

我假设正在使用依赖注入来创建这个工厂。应该有两种类型兼容第一个参数,MyUserManager或内置。

有没有办法确保选择MyUserManager,还是需要提供自定义UserClaimsPrincipalFactory?

当有多个符合论证的匹配服务时,DI会如何选择?

2016年2月26日更新:

我尝试删除默认用户管理器:

ServiceDescriptor defaultUserManager = services
    .Single(s => s.ServiceType.FullName.StartsWith("Microsoft.AspNet.Identity.UserManager"));

services.Remove(defaultUserManager);

加入我之前

services.AddScoped(typeof(MyUserManager<MyAppUser>))

这些线路运行良好,但后来抛出:

抛出异常:mscorlib.dll中的'System.InvalidOperationException'

  

其他信息:无法解析类型服务   “Microsoft.AspNet.Identity.UserManager 1[MyAppUser]' while attempting to activate 'Microsoft.AspNet.Identity.UserClaimsPrincipalFactory 2 [MyAppUser,   Microsoft.AspNet.Identity.EntityFramework.IdentityRole]”。

因此看起来DI引擎无法识别通过继承的兼容性。

2 个答案:

答案 0 :(得分:0)

我相信您需要使用.AddTransient函数或根据以下文档在ConfigureServices函数中使用ContainerBuilder:Asp.net 5 dependency injection

答案 1 :(得分:0)

DI选择最后注册的服务实现。

我认为您在注册实现类型而不指定预期服务类型的问题。 AddScoped调用应该更改为:

services.AddScoped(typeof(UserManager<>), typeof(MyUserManager<>));