I know this has been discussed ad nauseum...but I have an issue with the way Windsor is tracking Transient IDisposable objects.
I understand the benefits of letting Windsor manage my IDiposables...but I don't like it.
What happens if I want to wrap my component in a using block? The coder would make the assumption the resource would get cleaned up at the end of the using block, right? Wrong - Dispose would be called, but Windsor would hold onto the instance until explicitly released. This is all well and fine for me, since I know what I'm doing...but what about another developer who's coding a class and wants to use an IDisposable the way every other IDisposable is usually used - in a using block?
using(factory.CreateInstance())
{
....
}
looks much clearer to me than:
MyDisposable instance;
try
{
instance = factory.GetInstance();
}
finally
{
factory.Release(instance);
}
In order to truly dispose my instances and have them eligible for GC, I need to reference the WindsorContainer or use a typed factory that exposes a release method. That means the only acceptable way of using IDisposable components is to use a typed factory. This is not good, in my opinion...what if someone adds the IDisposable interface to an existing component? Every single place that expects the component to be injected will need to change. That's really bad in my opinion. (Granted, in a non DI scenario, it would need to change to call Dispose also...but with Windsor every place will need to change to use a typed factory, which is a much larger change).
Ok, fair enough, I can use a custom ReleasePolicy right? How about this?
public class CustomComponentsReleasePolicy : AllComponentsReleasePolicy
{
public override void Track(object instance, Burden burden)
{
if (burden.Model.LifestyleType == LifestyleType.Pooled)
base.Track(instance, burden);
}
}
Ok, great, my IDisposable Transient components will be GC'd now.
What if I want to use a TypedFactory so my class can produce many instances of a type?
public interface IMyFactory
{
MyDisposable GetInstance();
void Release(MyDisposable instance);
}
[Singleton]
public class TestClass
{
public TestClass(IMyFactory factory) { }
}
Ok, well, for one, calling Release on factory will do nothing to call Dispose() on MyDisposable, since MyDisposable isn't tracked....
How can I overcome these difficulties?
Thanks.