开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜