Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disposing object from same object

Tags:

c#

dispose

fluent

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?

like image 591
Matias Cicero Avatar asked Oct 16 '16 06:10

Matias Cicero


People also ask

What happens if Dispose is not called?

Implement a finalizer to free resources when Dispose is not called. By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory. However, if the Dispose method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer.

How do you use the dispose method?

The Dispose() methodThe Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.

What is disposed object?

A disposed object is an object that implements IDisposable that has had the Dispose method called. This could be called explicitly or after a using statement completes. If it's happening sporadically, it might be a race condition.

When to use Finalize and Dispose in net?

Microsoft recommends that we implement both Dispose and Finalize when working with unmanaged resources. The Finalize implementation would run and the resources would still be released when the object is garbage collected even if a developer neglected to call the Dispose method explicitly.


1 Answers

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.

like image 159
Dovydas Šopa Avatar answered Sep 29 '22 12:09

Dovydas Šopa