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?
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.