當前正在使用MVVM模式的MVC應用程序。它最初是這麼寫的,所有的ViewModels來自同一BaseViewModel,其中紡一個單一實體框架庫,像這樣繼承:使用多個實體框架上下文快速修復ViewModel
public abstract class BaseViewModel : INotifyPropertyChanged
{
private static MyRepository _rep;
protected static MyRepository rep
{
get
{
if (_rep == null)
_rep = new MyRepository();
return _rep;
}
}
}
的應用程序,我繼承了它實際上沒有單元測試,所以我決定做一些重構,使其更具可測性。所以我把一個接口在庫中,並給每個視圖模型自己的副本,因此它可以被嘲笑了測試:
public class MyViewModel : BaseViewModel
{
private IMyRepository _rep;
public AvailabilityHistoryViewModel()
: this(new MyRepository())
{ }
public MyViewModel(IMyRepository rep)
{
_rep = rep;
DoStuff();
}
}
這是罰款,大多數情況下。但後來我遇到了一個以前的功能按鈕,突然導致應用程序崩潰與可怕的「實體對象不能被IEntityChangeTracker的多個實例引用」錯誤。
事實證明,有一個用戶控件在應用程序中的幾個地方使用,它也從BaseViewModel繼承,因此它有自己的存儲庫副本。
public abstract class BaseTreeViewItem : BaseViewModel
{ }
當它被用作父視圖模型裏面,它的屬性是通過周圍,它很可能用的是別人與用戶控件庫被傳遞到視圖模型創建並保存其庫中的EF對象落得 - 因爲它們是不同的上下文,導致崩潰。
簡單的解決方法是簡單地退出我的更改,並讓使用此UserControl的ViewModel返回使用BaseViewModel存儲庫。但這很醜陋。一個適當的解決方法,重新排列的東西,使UserControl沒有自己的上下文,將需要更長的時間,我現實得到。有另一種方法嗎?
它會 - 實際上原來的模型有一個單身存儲庫。然而,要做到這一點並保持我的可測試性,需要我實施依賴注入,即使用像Ninject這樣的現成包裝,它本身也是一個完整的魚羣。還是我錯過了明顯的東西? –
是的,你應該實現依賴注入,這是一個非常好的模式,在你的架構中。起初它看起來可能是額外的工作,但它通過鬆耦合提供的靈活性極大地提高了代碼的可維護性和可測試性。 – dave
像Ninject一樣,實現一個好的基於框架代碼的框架並不像看起來那麼複雜。你在項目中做得越早,意味着工作就越少。他們在他們的[Dojo](http://www.ninject.org/learn.html) – dave