我希望我的 ApplicationContext
构造函数将 UserManager
作为参数,但我在依赖注入(inject)方面遇到了问题。
代码:
public class ApplicationContext : IdentityDbContext<ApplicationUser>
{
private IHttpContextAccessor _contextAccessor { get; set; }
public ApplicationUser ApplicationUser { get; set; }
private UserManager<ApplicationUser> _userManager;
public ApplicationContext(DbContextOptions<ApplicationContext> options, IHttpContextAccessor contextAccessor, UserManager<ApplicationUser> userManager)
: base(options)
{
_contextAccessor = contextAccessor;
var user = _contextAccessor.HttpContext.User;
_userManager = userManager;
ApplicationUser = _userManager.Users.FirstOrDefault(u => u.Id == _userManager.GetUserId(user));
}
}
在 startup.cs
中:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("RCI.App")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationContext>()
.AddDefaultTokenProviders();
services.AddAuthentication();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddOptions();
}
错误信息:
A circular dependency was detected for the service of type 'Microsoft.AspNetCore.Identity.UserManager`1[RCI.App.Models.ApplicationUser]'.
谁能指出我做错了什么?
最佳答案
如果您实际上不需要 UserManager
在构造函数中,您可以存储对 IServiceProvider
的引用相反:
private IHttpContextAccessor _contextAccessor { get; set; }
public ApplicationUser ApplicationUser { get; set; }
private IServiceProvider _services;
public ApplicationContext(DbContextOptions<ApplicationContext> options,
IHttpContextAccessor contextAccessor, IServiceProvider services)
: base(options)
{
_contextAccessor = contextAccessor;
var user = _contextAccessor.HttpContext.User;
_services = services;
}
然后,当您真正需要 ApplicationUser
时,例如打电话GetRequiredService<ApplicationUser>()
(在 Microsoft.Extensions.DependencyInjection
中定义):
var manager = _services.GetRequiredService<UserManager<ApplicationUser>>();
var user = manager.Users.FirstOrDefault(u => u.Id == _userManager.GetUserId(user));
当然,你可以使用Lazy<T>
第一次延迟加载管理器或用户,然后存储对它的引用。
一般来说,@poke 关于重新架构以避免此类循环依赖的说法是正确的,但将此答案留在此处以防其他人遇到类似问题并且重构不是一种选择。
关于c# - 依赖注入(inject)循环依赖.NET Core 2.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46354041/