question

Stesvis-5434 avatar image
0 Votes"
Stesvis-5434 asked Stesvis-5434 commented

Do injected resources automatically dispose in EF6?

Hello,
I am wondering if injected resources in EF6 automatically dispose or not.

For example I use UnitOfWork in my project:

public interface IUnitOfWork : IDisposable
{
    //...
}

Then I have:

public class UnitOfWork : IUnitOfWork
{
    //...

        private bool _disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

}


Now in my services or controllers, I use the UnitOfWork in the following way, to properly dispose it:

public class MyService : IMyService
{
    public void MyMethod()
    {
        using (var unitOfWork = new UnitOfWork())
        {
            unitOfWork.DoSomething();
        }
    }

}


However, my preferred method would be to inject the UnitOfWork like this:

public class MyService : IMyService
{
    private IUnitOfWork _unitOfWork;

    public MyService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public void MyMethod()
    {
        _unitOfWork.DoSomething();
    }

}


In this last scenario, will _unitOfWork be automatically/safely disposed? I would tend to say yes, but I don't want to risk leaving hanging resources...
Please note that I am using MVC5 and not .NET Core (should they behave differently), and that UnitOfWork is registered as singleton:

unityContainer.RegisterSingleton<IUnitOfWork, UnitOfWork>();


Thank you!

dotnet-entity-framework-coredotnet-entity-framework
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@Stesvis-5434, based on your description, I didn't see where is related to EF6. If you worry about the risk of disposing the object , you could dispose the object manually by using the code
_unitOfWork.Dispose().

0 Votes 0 ·

I thought I'd point out that I am using EF6 because I honestly don't know if maybe the behavior is different from .net core.
Yes I can manually dispose it, but I'd like to know if the resources are automatically disposed or not when they are used with injection...for practicality and also personal knowledge.
Thanks

0 Votes 0 ·

@Stesvis-5434, If you want the resources are automatically disposed, you could try to use the using statement to dispose the object automatically. Please refer to the link Is IDisposable.Dispose() called automatically?. The first answer describes that 'The preferable way for a client is to use the using statement which handles automatic calling of Dispose() even if there are exceptions.'




0 Votes 0 ·

1 Answer

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered Stesvis-5434 commented

Both Entity Framework 6 and Entity Framework Core when accessed as shown below

 using (var context = new NorthwindContext())
 {
     var customers = context.Customers.ToList();
 }

.

Or with .NET Core 5/C#9 and higher

 using var context = new NorthwindContext();
 var customers = context.Customers.ToList();

Will dispose of any scoped objects. Now if say your DbContext is scoped private in a class you need to dispose of it else if the app closes it will then dispose of it's resources.

Best practice is to wrap your code for EF in a using statement.

There are fringe cases were developer believed they had memory leakage yet usually a code rewrite resolve these issues.

Also, unless there is a compelling reason to use EF 6 consider moving to EF Core which has many improvements. Consider EF Core 6 which is a RC and due for proper release the second week of November of this year.





· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If we should wrap it in a using statement, then basically UnitOfWork should not be injected. Is that what you are saying?

0 Votes 0 ·

The Web program is stateless so I can't see why an object is hanging around. You should allow the IoC to control an objects lifetime. I wouldn't be using a Dispose() if the object is under the control of the IoC.

You should follow the 'new' is glue principles. The articles should apply to .NET Non Core or Core.

https://ardalis.com/new-is-glue/

https://docs.microsoft.com/en-us/archive/msdn-magazine/2016/may/asp-net-writing-clean-code-in-asp-net-core-with-dependency-injection

It's hard to unit test if you are newing up objects instead of mocking out objects that are being DI in a segment of code being UT.




0 Votes 0 ·

I know, DI would be much better. I would like to switch from using (var unitOfWork = new UnitOfWork()) to DI if it's safe to do so...
@DuaneArnold-0443 so bottom line is that you agree, not only it would be ok to apply that switch, but actually better, right?

I was just nervous because the using takes care of the disposal, but my understanding is that the IoC will do the same if I inject the IUnitOfWork, right?

0 Votes 0 ·