Earlier I asked this question. The answer to which resulted into another question like thou seeth before thee.
The initial problem
My problem is, that I have a custom MembershipProvider
using an AccountRepository
using an ObjectContext
. Because the MembershipProvider
is a Singleton
in MVC (as I understand), the AccountRepository
and its ObjectContext
should be injected once and stay there for the remainder of the MembershipProvider
's life time.
However, in my controllers I also use repositories with object contexts. In these controllers I need the object context to be shared between the repositories with a request. I have the following binding:
Bind<IMyContext>().To<MyObjectContext>().InRequestScope();
// put bindings here
Bind<IAccountRepository>().To<EFAccountRepository>
and in the Application_Start()
kernel.Inject(Membership.Provider);
The problem is that Ninject apparently calls dispose on the object context when it thinks the request is done (I think after 30 seconds).
My (not-working) solution
I noticed that when you set your bindings you can specify "when injecting into". The problem is, that I need "when injecting into when injecting into". I.e. when injecting the object context into the account controller when injecting the account controller into the membership provider. And I don't seem to have that...
Work-arounds I thought of (but don't really like).
- Don't hang
MyMembershipProvider
in MVC. Just pas an instance of it (behind and interface) to the controllers that need it like I do with repositories. Then Ninject will instantiate the provider per request. I don't like it because I'm sure MVC has a reason for instantiating the membership provider as a singleton. - Find an event that occurs every request and call
kernel.Inject
again in each event. Re-initializing the provider every request is nearly equivalent to re-instantiating, except dirtier. - Make a separate account repository for the membership provider to which I can bind in a different way. It doesn't seem right to change my object model because of Ninject.
Conclusion
IMHO the first work-around is the best. However, I much rather find a way to set Ninject to bind in the way I want.
What should I do?