Appropriate lifecycle for repository classes using Castle Windsor
When I started with Windsor I thought DI would be simple. Now it's causing me more and more confusion.
A repository strikes me as a class with a singleton lifecycle. I should have a single instance of a FooRepository to load and save Foos to the database during the application's lifetime.
However, each repository holds a reference to a UnitOfWork, which does the dirty checking, works with the database etc. The UnitOfWork has a lifecycle of PerWebRequest - it makes no sense at all for the UnitOfWork to be a singleton, as a singleton instance could (for example) flush the changes made by several user sessions at the same time.
So then I have a singleton FooRepository holding a reference to a UnitOfWork, which at the end of the session gets disposed! I'm not even sure what effec开发者_运维问答t that would have on the repository's behaviour, but it doesn't sound good.
Can anyone explain, in simple English (okay, maybe with some code), the appropriate way to manage the lifecycle of Repository and UnitOfWork classes in a web app?
Rule of thumb is - component should not depend on other components that will outlive it.
In other words, it's ok for transient to depend on singleton, or per-web-request component, but not the other way around.
The way I approach Repository - UoW scenario is my UoW is per web request, but repositories are stateless and transient.
When you say repository, I assume you mean a repository which abstracts an Nhibernate session. If so, then it should never ever be singleton. If it is a singleton, then multiple request threads will trample over one another's session. I personally have seen a few defects around this. Since Castle's default life cycle is singleton, if a developer forgets to explicitly mark a component's life cycle, bad things start happening.
It should ideally be per-request (following the unit of work concept). The only rider to this approach is that you have enable Asp.net compatibility mode in your application (if it's not Asp.net that is). The other way is to mark a repository transient. But the downside to this approach is that Castle will instantiate a new repository object every time a component needs it.
精彩评论