2010-09-03 2 views
3

J'ai toujours su que tous les bons programmeurs appellent Dispose sur tout objet qui implémente IDisposable, cas dans la classe ObjectContext dans EF.Assurer IDisposable appel sur les objets créés dans le contrôleur et remis à la vue

Je suis nouveau à asp.net mvc si cela peut être une question noob, mais ici va ...

public ActionResult Index() 
    { 
     using (var db = new MyObjectContext()) 
     { 
      return View(db.People); 
     } 
    } 

Si je lance ce code, je reçois une erreur (ObjectDisposedException) parce que le ObjectContext a été disposé avant que la vue ne prenne des mesures sur les données. Y a-t-il une approche différente ici? Comment puis-je m'assurer que mes objets soient éliminés le plus rapidement possible?

Répondre

8

substituez la méthode Controller.Dispose() et éliminer de votre objet là-bas:

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); 
} 

Le framework MVC appellera automatiquement Controller.Dispose() à la fin de la demande.

2

Je vous recommande d'utiliser ViewModels et de ne transmettre que des modèles de vue aux vues. De cette façon, vous n'avez pas à vous soucier de disposer. Aussi abstrait et séparer votre accès aux données dans un référentiel:

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); 
    } 
} 

Maintenant, la disposition du référentiel est une préoccupation de son créateur qui, si vous suivez les bonnes pratiques est un cadre d'injection de dépendance. Afin d'instancier votre contrôleur, vous avez besoin d'une instance d'un référentiel à passer dans le constructeur et la plupart des bons frameworks DI vont disposer automatiquement les objets qui implémentent IDisposable.

Questions connexes