Let's say I have a factory which creates a service based on a disposable resource. I think the first solution is the cleanest one but I can't figure it out how to dispose 'instance' in my case. The second one would be a solution but that could be called a factory? I don't think so because that holds a proper resource. Furthermore 'DisposableIOResource' is that kind of service which is hard to create and that you just want to hide behind a factory. Is there a good pattern to solve this scenario? Below my two draft snippets.
// first solution
public class ServiceFactory
{
public Reader CreateReader(string configuration)
{
var instance = new DisposableIOResource(configuration);
return new Reader(instance);
}
}
// first solution - use case
var serviceFactory = new ServiceFactory();
var reader = serviceFactory.CreateReader(configuration)
reader.DoSomething(); // NOTE! How do I dispose 'instance'???
// second solution
public class ServiceFactory : IDisposable
{
private readonly DisposableIOResource _instance;
public ServiceFactory(string configuration)
{
_instance = new DisposableIOResource(configuration);
}
public Reader CreateReader()
{
return new Reader(_instance);
}
public void Dispose()
{
_instance.Dispose();
}
}
// second solution - use case
using(var serviceFactory = new ServiceFactory(configuration))
{
var reader = serviceFactory.CreateReader():
reader.DoSomething();
}
--- Edit I ended up whit another solution maybe a cleaner one:
public interface IDisposableIOResourceFactory
{
DisposableIOResource Create();
}
public class DisposableIOResourceFactory : IDisposableIOResourceFactory
{
private readonly string _configuration;
public DisposableIOResourceFactory(string configuration)
{
_configuration = configuration;
}
public DisposableIOResource Create()
{
return new DisposableIOResource(this._configuration);
}
}
// third solution
public class ServiceFactory
{
public Reader CreateReader(IDisposableIOResourceFactory resourceFactory)
{
return new Reader(resourceFactory);
}
}
public class Reader
{
public Reader(IDisposableIOResourceFactory resourceFactory) {}
public void DoSomething()
{
using var resource = resourceFactory.Create();
// work on resource
}
}
// first solution - use case
var serviceFactory = new ServiceFactory();
var resourceFactory = new DisposableIOResourceFactory();
var reader = serviceFactory.CreateReader(resourceFactory);
reader.DoSomething();
Your factory isn't the thing that needs to implement IDisposable. Your Reader does.
This is okay.
You don't include the class
ReaderBut it should implement IDisposable
Then when you create one, you put that into a using