gio
gio

Reputation: 91

Factory which creates disposable objects

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

Answers (1)

Kaddyuk
Kaddyuk

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

Related Questions