Search code examples
c#disposefluent

Disposing object from same object


I'm designing a fluent API and the usage is somewhat like this:

IUser user = work
                 .Timeout(TimeSpan.FromSeconds(5))
                 .WithRepository(c => c.Users)
                 .Do(r => r.LoadByUsername("matt"))
                 .Execute();

So, let's say that work is of type IUnitOfWork, but the method WithRepository(c => c.Users) returns an interface called IActionFlow<IUserRepository> which is IDisposable.

When I call Execute() and get the final result, I lose the reference to that IActionFlow<IUserRepository> instance so I can't dispose it.

What are the disadvantages of having the instance dipose itself on the Execute() method?

Something like:

public TResult Execute()
{
    // ...
    Dispose();
    return result;
}

The code seems to compile just fine but I'm looking for strange behaviors or bugs that may rise because of this. Is it bad practice at all?


Solution

  • You can have Using method like this:

    public static TResult Using<TDisposable, TResult>(Func<TDisposable> factory,
        Func<TDisposable, TResult> fn) where TDisposable : IDisposable {
        using (var disposable = factory()) {
            return fn(disposable);
        }
    }
    

    Then your code would look like this:

    var user = Using(() => work.
        Timeout(TimeSpan.FromSeconds(5)).
        WithRepository(c => c.Users),
        repository => repository.Do(r => r.LoadByUsername("matt")).
            Execute());
    

    This will allow your API to stay fluent and at the same time you will dispose WithRepository the same moment Execute is completed.