0
  • I am using asp.net mvc 3, entity framework with structure map for IoC.
  • I have my own custom membership provider.
  • I had the same kind of problem when I was injecting the dbcontext object and the membership instances using StructureMap so removed this for my UserRepository.
  • The UserRepository now has a DBContext property which is initialised in the constructor.

Everytime a new user is created/updated (the method doing this is wrapping the dbcontext object in using statement), the next time the dbcontext is referenced I get ObjectDisposedException thrown.

I don't understand what I am doing wrong. Obviously, the membership provider class isn't instantiating the userRepository object everytime it needs it and when a user is updated, the context is disposed because of the using statement. But I thought this was standard practice?

Any help is greatly appreciated.

EDITED:

There is no complex code really. The set up is:

CustomMembershipProvider overrides the standard Membership provider (config file has got the details). CustomMembershipProvider uses IUserService object that uses IUserRepository which is implemented by UserRepository that has the DBContext private object at class level.

In the UserRepository, I've got:

    public void UpdateUser(User user)
    {
        using(_db)
        {
            ... code to indicate that the user state has changed
            _db.SaveChanges();
        }
    }

Once this code is run, the request is complete. But when another request is made to retrive role information or read the user from the database (in the UserRepository class), I get the ObjectDisposedException thrown. At this point nothing related to User Or Role works because they use the same UserRepository class whose _db variable has been disposed by UpdateUser.

I initially had StructureMap resolve the DBContext object, the customMembership object etc but have had to since remove it from StructureMap's mapping.

amythn04
  • 388
  • 2
  • 11

1 Answers1

3

Everytime a new user is created/updated (the method doing this is wrapping the dbcontext object in using statement), the next time the dbcontext is referenced I get ObjectDisposedException thrown.

DbContext is a disposable resource(Which implements IDisposable). So when you wrap it in a using block the context is disposed when the control flow goes out of the using block.

using(myContext)
{
   //do stuff
}

//try to access myContext after the using block throw ObjectDisposedException

You have to re-design how you use the DbContext and when you are going to dispose it.

Eranga
  • 32,181
  • 5
  • 97
  • 96
  • I realise that DBContext is disposed in a Using statement. But that is standard practice, isn't it? I have resolved this now by instantiating a new object of "UserRepository" in each of the membership class' methods. I think the Membership & Role providers do not instantiate the underlying object that it needs to use to connect to the database for auth. At least that is what I have seen. Using structureMap to resolve the object doesn't work because the dbcontext will be disposed when there is an update operation on the user object. It might be something I'm doing wrong but I'm not sure – amythn04 Jul 12 '11 at 10:26
  • I will post the StructureMap mappings from the Global.aspx.cs later but I have already edited my original question with a little bit more information about the set up and code. – amythn04 Jul 12 '11 at 10:54
  • @amythn04 we also create new context each time a membership provider method is called – Eranga Jul 12 '11 at 11:13
  • Does that mean Membership provider will create the DAL/Service object (in my case IUserService) as a singleton if we make it a class level object? If yes then that is news to me! Also, do you use any DI/IoC framework? If you do, are you wiring the membership provider? I did this initially but this gives me the object disposed exception - http://martinsantics.blogspot.com/2009/10/wiring-up-membership-provider-with.html – amythn04 Jul 12 '11 at 12:42
  • Membership Provider is used as a singleton. Framework does not provider entry points for DI. Hence you can't DI properly(but you can manually do by calling `Resolve<>()` methods). The sample wrapper API(your link) allows you to DI. – Eranga Jul 12 '11 at 14:21