Reputation: 91
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();
Upvotes: 0
Views: 649
Reputation: 107
Your factory isn't the thing that needs to implement IDisposable. Your Reader does.
This is okay.
// first solution
public class ServiceFactory
{
public Reader CreateReader(string configuration)
{
var instance = new DisposableIOResource(configuration);
return new Reader(instance);
}
}
You don't include the class Reader
But it should implement IDisposable
public class Reader : IDisposable
{
private readonly DisposableIOResource _instance;
// Code Here
public Reader(DisposableIOResource instance) {
_instance = instance;
}
public void Dispose() {
_instance?.Dispose();
}
}
Then when you create one, you put that into a using
var serviceFactory = new ServiceFactory(configuration);
using(var reader = serviceFactory.CreateReader()) {
reader.DoSomething();
}
Upvotes: 2