Zilberman Rafael
Zilberman Rafael

Reputation: 1451

.NET WebApi hits dispose before the action

I have WebApi controller that manages users accounts. The controller has 3 methods: The constructor - gets parameter of type UserManager<IdentityUser> which is injected automaticly by ninject. Dispose - disposing the UserManager. Register Action - registering new user.

I set breakpoints in Register action and Dispose method.

Note: The Register action called using ajax.

NinjectWebCommon.cs

kernel.Bind<UserManager<IdentityUser>>().ToConstant(Startup.UserManager);

AccountController.cs

private readonly UserManager<IdentityUser> _userManager;


public AccountController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}

[Route("api/Account/Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{ // **<---- Breakpoint**
        // code...
}

protected override void Dispose(bool disposing)
{ // **<---- Breakpoint**
    if (disposing)
    {
        _userManager.Dispose();
    }

    base.Dispose(disposing);
}

After I press F5 (Start with debugging) the breakpoint inside Dispose method hits first. Then I filling the form and sending the request to Register action, the breakpoint inside it hits.

The problem is that the UserManager getting disposed before the action happens, How I can fix the code so the UserManager will dispose after the application stops?

Upvotes: 2

Views: 1852

Answers (2)

Zilberman Rafael
Zilberman Rafael

Reputation: 1451

When you disposing static object in controller (that disposing every request), at the next request, you are not going to be able to use the object on a second request.

Also, there is no need to dispose objects which was binded using InSingletonScope or ToConstant because they disposed automatically by Ninject. If you want to create one instance for an object you should bind him using InSingletonScope or ToConstant (as described in Ninject wiki) then your object disposed when the kernel is disposed. Other way every time the binding will be injected, new instance of the object will be created.

Here is the fixed version of the code:

NinjectWebCommon.cs

kernel.Bind<UserManager<IdentityUser>>().ToConstant(Startup.UserManager); // Disposed when the kernel is disposed

AccountController.cs

private readonly UserManager<IdentityUser> _userManager;


public AccountController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}

[Route("api/Account/Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
        // code...
}

Upvotes: 3

Darrel Miller
Darrel Miller

Reputation: 142134

Controllers are instantiated and disposed on every request. If you pass in a singleton to the ctor and then dispose the singleton when the controller is disposed then you are not going to be able to use the singleton on a second request.

Why don't you just dispose Startup.UserManager on some global application shut down event?

Upvotes: 2

Related Questions