The scope attribute, and reusing configurations
We have a sizable Spring.NET configuration file for a website, with many request singleton objects. We need to be able to use many of these objects in non-web multi-threaded scenarios as well. However, in those non-web scenarios, we need to be able to dump all the request singleton objects when we wish to change the context for the thread (we've added our own thread-safe adaptation of Spring using ThreadLocal storage, let's not divert on that).
So, multi-threading is not a problem, but changing our context is. All of those things marked as scope="request" are now singletons for the lifetime of the thread. We can't drop them from memory because Spring won't let us do that.
Solution A: make the objects mutable. We see that as a bad design. These objects have state and we can't just switch out parts of the state. Requiring all objects to have alterable state just isn't an option.
Solution B: use different configurations, and use prototypes. This doesn't suit well because we have a large team and managing these dependencies in multiple places is not a reliable solution. That could potentially be solved via automation, but we also feel using prototypes for many of these objects would be detrimental to performance.
Solution C: alter the Spring.NET codebase to provide the capability to dump a named scope (in this case, the one called "request"). This is a generalization of the request scope in the object factory for the web. It's using HttpContext as the backing store, which gets reclaimed at the end of the request. We'd generalize that, refactor the current web object factory to push its general logic up into core, calling the feature "named scopes." We'd also have to expose a way for cycling a named scope. Then our non-web applications could simply call this method to recycle the "request" scope. Request scope in the web context would function the same as it does today.
Solution D: we're doing it wrong. Maybe we've missed something, are taking the wrong approach. Lil' help?
("Are you *really* the head of Quikie Mart?")
Last edited by dpurrington; 02-09-2009 at 04:35 PM.
Solution D: Reset all singletons. This would work and be a less intrusive change. That's what we're going with at this point.
I'm still interested in the feedback, so if someone comes along at some point in the future, please post a reply.
Spring.NET 2.0 will introduce custom scopes which probably is exactly what you are looking for. Unfortunately we're not there yet...
My first idea would be to implement my own IFactoryObject. It would return false from "IsSingleton" and manage the scope/lifecycle of the "product" object itself.
The second idea is to write an IObjectFactoryPostProcessor that automatically wraps all "request"/"session"-scoped objectdefinitions in such a FactoryObject outside of a web context.
Can you please clarify what you are exactly trying to do? Are you talking about reusing configuration files or spawning threads from within the webapp? I'd also like to hear more about your "threadsafe adaption" - what was the issue?
Thanks for the response.
The reason I need this is because I have many objects (services) that have state based on request information. This same state is used outside of the website in order to perform various operations. I perform a set of operations for one context, then perform another set of operations in another context. So I can't use singletons because I have to change state from one operation set to the next. On the other hand, prototype configuration would not be performant.
The issue I had with thread safety was again in the non-web environment. I needed to scope singletons to the thread. I accomplished this by putting the ApplicationContext in a thread static field, so I have a spring context for each thread.