2010-09-03 53 views
3

我一直都知道,所有優秀的程序員都調用Dispose實現IDisposable的任何對象,例如EF中的ObjectContext類。確保對在控制器中創建的對象進行IDisposable調用並將其傳遞到視圖

我是新來asp.net的MVC所以這可能是一個noob問題,但在這裏不用...

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

如果我運行此代碼我得到一個錯誤(的ObjectDisposedException),因爲ObjectContext中已經佈置在視圖對數據採取行動之前。這裏有不同的方法嗎?我怎樣才能確保我的物品儘快被處理掉?

回答

8

重寫Controller.Dispose()方法,並在那裏你對象的處理:

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

MVC框架會在請求結束時自動調用Controller.Dispose()。

2

我會推薦你​​使用ViewModels並只將視圖模型傳遞給視圖。這樣你就不用擔心處理了。也是抽象和分離數據訪問到存儲庫:

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

現在倉庫的處置是它的創造者關心的問題,如果你遵循良好做法是一個依賴注入框架。爲了實例化你的控制器,你需要一個存儲庫的實例傳遞給構造器,大多數好的DI框架將自動處理實現IDisposable的對象。

相關問題