Ensuring IDisposable call on objects created in the controller and handed off to view
I have always known that all good programmers call Dispose on any object that implements IDisposable, case in point the ObjectContext class in EF.
I am new to asp.net mvc so this may be a noob question but here goes...
public ActionResult Index()
{
using (var db = new MyObjectContext())
{
return View(db.People);
}
}
If I run this code I get an error (ObjectDisposedException) because the ObjectContext has been disposed of before the 开发者_开发百科View takes action on the data. Is there a different approach here? How can I ensure my objects get disposed of as soon as possible?
Override the Controller.Dispose() method and dispose of your object in there:
private IDisposable _objectToDispose;
public ActionResult Index() {
var db = new MyObjectContext();
_objectToDispose = db;
return View(db.People);
}
protected override void Dispose(bool disposing) {
if (disposing && _objectToDispose != null) {
_objectToDispose.Dispose();
}
base.Dispose(disposing);
}
The MVC framework will automatically call Controller.Dispose() at the end of the request.
I would recommend you using ViewModels and passing only view models to the views. This way you don't have to worry about disposing. Also abstract and separate your data access into a repository:
public interface IPersonRepository
{
IEnumerable<Person> GetPeople();
}
public class PersonRepositorySql : IPersonRepository, IDisposable
{
private MyObjectContext _db = new MyObjectContext();
public IEnumerable<Person> GetPeople()
{
return _db.People;
}
public void Dispose()
{
_db.Dispose();
}
}
public class HomeController : Controller
{
private readonly IPersonRepository _repository;
public HomeController(IPersonRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
IEnumerable<Person> people = _repository.GetPeople();
// Using AutoMapper here but could be anything:
IEnumerable<PersonViewModel> peopleViewModel = Mapper
.Map<Person, PersonViewModel>(people);
return View(peopleViewModel);
}
}
Now the disposal of the repository is a concern of its creator which if you follow good practices is a Dependency Injection framework. In order to instantiate your controller you need an instance of a repository to be passed into the constructor and most good DI frameworks will automatically dispose objects that implement IDisposable
.
精彩评论