Reputation: 1
I am working on asp.net mvc-4 web application and entity framework 5.0. now i am confused on how Dispose is working inside my application. currently i have the following settings:-
-I have a APIRepository class which contain multiple methods that use WebClient()
to do external API calls. and i do not define any Dispose method inside this class.
public class APIRepository
{
public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor)
{
//code goes here
using (var client = new WebClient())
{
}
return result;
}
//code goes here
}
-I have a Repository class which contain my data access logic, and it initiate my DbContext
, and i define a Dispose method inside this class.
public class Repository
{
private MyEntities my = new MyEntities();
//code goes here...
public void Dispose()
{
my.Dispose();
}
-I have a Controller class, which initiate the two repository classes:-
[RequireHttps]
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
//code goes here
protected override void Dispose(bool disposing)
{
if (disposing)
{
repository.Dispose();
}
base.Dispose(disposing);
}
now i have the following questions about my current project:-
Based on my understanding on how Dispose works, is that when an action method calls a View, then asp.net mvc will automatically calls the Dispose method inside my current Controller class. which in turn calls the Dispose method inside my repository , which will make sure that the database connection is closed. so is my understanding valid ?
in my case do i need to have a Dispose method inside my APIRepository() , which as i mentioned this repository only have WebClient()
calls to integrate with 3rd party application, and it will return object or simple string to the action method.??
what are the operations that need to be Disposed? as i know calling a my.Dispose();
inside my repository class will make sure that the database connection is closed.. but are there other operations that need to be disposed? such as initiating a WebClient()
or returning a JSON by my action method?
what are the actions other than returning a View will call the Dispose method inside my Controller class ?
Upvotes: 1
Views: 7574
Reputation: 29202
If you use dependency injection then none of the classes would be responsible for creating or disposing the dependencies injected into it.
Instead of this:
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
where ServerController
creates its dependencies and is responsible for disposing of them, this:
public class ServerController : Controller
{
private readonly Repository _repository;
private readonly APIRepository _apiRepository;
public ServerController(Repository repository, APIRepository apiRepository)
{
_repository = repository;
_apiRepository = apiRepository;
}
Now whatever creates an instance of ServerController
is responsible for instantiating those objects and disposing of them. That "whatever" is typically your dependency injection container, like Windsor or Unity. Or even better, in ASP.NET Core it's built in and you don't need to add a separate container.
The short version: The container creates your repository, and if it needs to be disposed, it disposes it. You can even specify details about the lifetime of certain dependencies. If it's not disposable and can be reused then it's a singleton. You can create and dispose a new instance every time you need one. Or you can create a new instance that's tied to a given web request. That request uses it and then it's disposed.
Upvotes: 5
Reputation: 54628
which will make sure that the database connection is closed. so is my understanding valid ?
Your database connection is closed way before the dispose method is called. It would be a very rare circumstance that it is not.
in my case do i need to have a Dispose method inside my APIRepository()
Only if you are managing the disposable of objects at field level instead of a method level.
// The method is disposing of the object
public class NotDisposable
{
public string GetString()
{
string result;
// This is disposed by the time the method exists.
using(var disposable new Disposable)
{
result = disposable.GetString()
}
return result;
}
}
// This class has a field that it needs to dispose
// so it inherites from IDisposable
public class Disposable : IDisposable
{
private bool _isDisposed;
private readonly IDisposable _somethingToManuallyDispose;
public Disposable()
{
somethingToManuallyDispose = new SomethingImplementsIDisposable();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !_isDisposed)
{
_isDisposed = true;
// Dispose Managed Resources
if (_somethingToManuallyDispose != null)
{
_somethingToManuallyDispose.Dispose();
}
}
}
}
but are there other operations that need to be disposed?
Example above, where you do not Dispose of an object in the method.
what are the actions other than returning a View will call the Dispose method inside my Controller class
That sentence doesn't even make sense. Returning a View does not call Dispose. The MVC/API Pipeline Disposes of the controller after the response is sent to the client, and only if it implements IDisposable
.
Please consider reading MSDN - Dispose Pattern and MSDN - Implementing a Dispose Method and MSDN - Using Objects That Implement IDisposable.
Upvotes: 4