I'm used to the approach when it is the object that creates another object (either directly or through factories, builders, etc) - is the one that "owns" it, thus manages its lifetime.
This idea works fine in almost every case.
But sometimes the one that creates an object simply cannot manage it, for instance in the builder design pattern implementation:
IFoo BuildFoo()
{
var dep = new Dep();
return new Foo(dep);
}
So, here the builder cannot manage the lifetime of the dep object since:
Dispose it.The naive solution would be to make Foo : IDisposable and let it manage the Dep passed to its constructor.
But then another dilemma arises:
using (var dep = new Dep())
{
using (var foo = new Foo(dep))
{
// (1) do something with foo
}
// (2) !!! do something with dep !!!
}
The code above becomes unsafe: at the point (2) it's not safe to use dep since it is already Disposed by foo.
And there is nothing syntactically that can denote, whose responsibility it is to manage the lifetime of an object.
So the question: what would be a general solution for that?
In this case, I wouldn't worry about it. I'm going to get shot to pieces here, I imagine, but "builders", "factories" etc are all places where I think it's okay to create an object and hand off it's disposal to the thing that asked for it.
There is a rule though that the builder/factory must only be creating the object, and not doing anything with it.
Of course, if you're newing-up objects using the new keyword, then you're coupling yourself to that implementation (even if it's indirectly via a factory class). You might want instead to consider dependency injection, depending on what the created objects are for, in which case a DI container would create the objects and dispose them for you at the correct time, based on their configured lifestyle.
very naive implementation
void Main()
{
using (var builder = new Builder())
{
var foo = builder.Create();
// do smtg
}
}
public class Foo
{
public Foo(Dep instance)
{
}
}
public class Dep : IDisposable
{
public void Dispose()
{
Console.WriteLine($"{this.GetType().Name} disposed!");
}
}
public class Builder : IDisposable
{
private List<IDisposable> _disposables = new List<System.IDisposable>();
public Foo Create()
{
var dep = new Dep();
_disposables.Add(dep);
var foo = new Foo(dep);
return foo;
}
public void Dispose()
{
foreach(var d in _disposables)
d.Dispose();
Console.WriteLine($"{this.GetType().Name} disposed!");
}
}
If something owns IDisposable, then it should implement IDisposable. And, ofcourse, this is very naive impl, just as sample.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With