在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引擎无法识别通过继承的兼容性。
答案 0 :(得分:0)
我相信您需要使用.AddTransient函数或根据以下文档在ConfigureServices函数中使用ContainerBuilder:Asp.net 5 dependency injection
答案 1 :(得分:0)
DI选择最后注册的服务实现。
我认为您在注册实现类型而不指定预期服务类型的问题。 AddScoped调用应该更改为:
services.AddScoped(typeof(UserManager<>), typeof(MyUserManager<>));