I wrote my custom middleware which I add in
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseAutologin();
app.UseMvc(routes =>
{
//...
So it is the last middleware before the Mvc comes into play.
In my middleware's Invoke
method I want to (indirectly) access the DbContext
.
public async Task Invoke(HttpContext context)
{
if (string.IsNullOrEmpty(context.User.Identity.Name))
{
var applicationContext = _serviceProvider.GetService<ApplicationDbContext>();
var signInManager = _serviceProvider.GetService<SignInManager<ApplicationUser>>();
var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false);
}
await _next(context);
}
Nearly every time I get the following exception:
InvalidOperationException
: An attempt was made to use the context while it is being configured. ADbContext
instance cannot be used insideOnConfiguring
since it is still being configured at this point.
Now this is clearly raised by the PasswordSignInAsync
method. But how can I ensure that the model was created before doing such things?
Maybe I was not entirely clear: I don't want to use the DbContext
myself - the PasswordSignInAsync
uses it when verifying the user and password.
What if you inject the ApplicationDbContext
and SignInManager<ApplicationUser>
through the Invoke
method:
public async Task Invoke(HttpContext context, ApplicationDbContext applicationContext, SignInManager<ApplicationUser> signInManager)
{
if (string.IsNullOrEmpty(context.User.Identity.Name))
{
var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false);
}
await _next(context);
}
This way you the services are resolved from the correct scope. I notice you don't actually use the ApplicationDbContext
anywhere, just the SignInManager
. Do you really need it?
This error is likely occurring because any middleware acts as a singleton. You have to avoid using member variables in your middleware. Feel free to inject into the Task Invoke, but don't store the inject value into a member object.
See: Saving HttpContext Instance in Middleware, Calling services in Middleware
I was able to get around this myself, by creating a class that I could then pass into other methods in my middleware:
public async Task Invoke(HttpContext context, IMetaService metaService)
{
var middler = new Middler
{
Context = context,
MetaService = metaService
};
DoSomething(middler);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With