I have a web API and using Autofac
for DI.
In startup method, I am configuring auth using app.CreatePerOwinContext (AppDbContext, UserManager and SignInManager).
I am also configuring autofac
here and registering controllers and other required types and modules.
I am also registering OwinContext
with DI and in one of the library used by my API, I am doing constructor injection of IOwinContext
When I make a first API request, Context.GetUserManager() works fine, but after first request it always throws "Cannot access a disposed object.\r\nObject name: 'ApplicationUserManager'."
My controllers are registered using InstancePerRequest() My Library is registered using InstancePerLifetimeScope()
Same code works fine with an ASP.Net Web application if I bypass my API and make direct calls to my library code.
I tried so much but I am not able to figure out the proper solution.
Startup.cs class (Web Api)
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//Add cors middleware
app.UseCors(CorsOptions.AllowAll);
//http Configuration
var config = new HttpConfiguration();
WebApiConfig.Register(config);
//Configure authentication
ConfigureAuth(app);
//Configure DI Container
AutofacConfig.Register(app, config);
app.UseWebApi(config);
}
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
}
}
DI Registration
public class AutofacConfig
{
public static void Register(IAppBuilder app, HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder.Register(c => HttpContext.Current.Request.GetOwinContext()).As<IOwinContext>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
//this is in another module in different library which I am calling from here using builder.RegisterModule
builder.RegisterType<UserManager>().As<IManager<User>>().InstancePerLifetimeScope();
//Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// Register the Autofac middleware FIRST, then the Autofac Web API middleware,
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
}
}
Here is my UserManager
public class UserManager: IManager<User>
{
private ApplicationUserManager _applicationUserManager;
private readonly IOwinContext _context;
protected ApplicationUserManager ApplicationUserManager
{
get => _applicationUserManager ?? _context.GetUserManager<ApplicationUserManager>();
set => _applicationUserManager = value;
}
public UserManager(IOwinContext context)
{
_context = context;
ApplicationUserManager = context.GetUserManager<ApplicationUserManager>();
}
public User GetById(int? id)
{
//This throws System.ObjectDisposedException ('Cannot access a disposed object.Object name: 'ApplicationUserManager'.') after first API request.
var user = ApplicationUserManager.FindByEmail(entity.UserName);
return entity;
}
}