I want my ApplicationContext
constructor to have the UserManager
as a parameter, but I am having trouble with dependency injection.
Code:
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));
}
}
And in 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();
}
Error message:
A circular dependency was detected for the service of type 'Microsoft.AspNetCore.Identity.UserManager`1[RCI.App.Models.ApplicationUser]'.
Could anyone point out what I'm doing wrong?
Save()
method but it would be much easier to just have it in the context in one place instead – AcquiescenceUserManager<ApplicationUser>
andApplicationContext
in your example have explicit dependencies on each other, resulting in a circular dependency. when resolvingApplicationContext
it has to create anUserManager<ApplicationUser>
which needs aApplicationContext
. You see where that is going? – HobnailedUsers
within the application context. make your query directly on that with the the current request's user id. no need to reference the user manager at all. – HobnailedUserManager<ApplicationUser>
is dependant onApplicationContext
? – AcquiescenceUserManager
is dependant on the context. Here is the ctor:public UserManager(IUserStore<TUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<TUser> passwordHasher, IEnumerable<IUserValidator<TUser>> userValidators, IEnumerable<IPasswordValidator<TUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<TUser>> logger);
– AcquiescenceUserManager<T>
depends onUserStore<T>
which depends on the database context that’s registered with ASP.NET Core Identity, which happens to be your database context that depends on the user manager. – LavalleeApplicationContext
constructor lean and not try to access the user or make queries within there. extract the user and make your queries within the target methods as the request would have been fully realized by then. It should basically only have_contextAccessor = contextAccessor;
the rest should be done on one of the crud operations. – Hobnailed