Castle Windsor - Do I have to release singleton or non-disposable transient objects?
Asked Answered
B

1

11

The Castle wiki says at several places I should ALWAYS call container.Release() for components resolved through the container. This obviously makes sense for sophisticated life-style management techniques (e.g. LifeStyle.Pooled) or when using specialized facilities...

But do I really have to release singleton (which live until the container is disposed) and non-disposable transient objects? If I step through Release() calls for transient objects or singletons these calls seem to be superfluous - .e.g. in the case of transient objects not implementing IDisposable the kernel simply notices that it has no track of the object and returns...

There seems to be the concept of a "component burden" to track "indirect" references to other disposable components that might be constructed while resolving a transient object. I understand that it is necessary to release transient objects if you do not know 100% whether they have such indirect dependencies or not. Is this the main reason to "urge" all Castle users to ALWAYS release components?

Berstine answered 26/7, 2010 at 11:2 Comment(0)
N
21

Castle Wiki is a bit strict here - trying to be safe rather than sorry. It could use some rewording there probably.

Anyway - here's how it works.

Windsor (by default) tracks most components and it holds reference to them which stops Garbage Collector from collecting them. This is not a bug - it's a feature, and a extremely useful and powerful one. In most cases you should not assume if a component will be tracked or not. A non-disposable component that has disposable dependencies will also be tracked. This is in general rule: "components that either themselves of some of their dependencies have any decommission steps are tracked by default release policy in Windsor".

Now, here's the part where lifetimes come into play.

  • Singleton - by definition singleton are "global" in the context of the container - they get created when you first request them and live for the rest of the lifetime of the container (which means until the container gets disposed). If you see documentation, it actually says that releasing singletons actually doesn't do anything. It's only when the container gets disposed that decommission concerns of your lifetime components will get called.

  • Per (context: web request/WCF Session/) - since the object is shared in a well defined context with a well define end, end of the context will take care of releasing your components.

  • Transient - That's where the real issues can creep in. Since transient components don't have any end arbitrary end of lifetime and you can produce heaps of their instances during the lifespan of the app, there's no other way than being explicit and saying to the container "hey, I'm not gonna use this object anymore, feel free to get rid of it, thanks for all the fish."

Now the reason why the documentation suggest always releasing the components is that the code that uses components should not really know what the lifetime of a component is. It is not always the case, and often in applications there are components that "naturally" fit a lifestyle. In general however, like I said it's about being safe rather than sorry.

Another thing is where you call the Resolve and Release. You should only ever Release what you Resolve.

When you use the container in similar manner to how I do it, you may not have to call Release anywhere in your code. You will Resolve your root, but Dispose of the container itself will take care of releasing it. You will likely also resolve other components implicitly via typed factories, and in this case you should also release them (via the factory), but that's usually it.

So the end result is, it's not as scary as it sounds at first.

Nacreous answered 26/7, 2010 at 11:41 Comment(3)
Thanks Krzysztof! That was the answer I was looking for. Regarding Release and the container: Your recommendation to avoid the "service locator pattern" (avoid passing the container around) is of course very right. I was mainly asking the question because the "release question" is the same for factories created by the factory facility.Berstine
A caveat to the rules explained by Krzysztof is that if you create an object yourself and register your instance with the container (rather then letting the container create an instance for you), then container will leave the management of that instance's life cycle up to you. I.e. even though you register it as a singleton, the container will not dispose of it when you dispose of the container.Rooke
correct. Ultimately it's for ILifestyleManager to decide, and in upcoming Windsor 3 lifestyle managers have even more control here.Nacreous

© 2022 - 2024 — McMap. All rights reserved.