我開發一個C#之前創建/ WPF/MVVM/UWP應用程序,它使用了ViewModelLocator它看起來像這樣:確保一個靜態類是在其他
public class ViewModelLocator
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainPageViewModel MainPage
{
get
{
return ServiceLocator.Current.GetInstance<MainPageViewModel>();
}
}
static ViewModelLocator()
{
// DEBUG LINE: var test = Views.ViewLocator.MainPageKey;
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainPageViewModel>();
}
}
我有另一個類,一個ViewLocator,用於導航目的,看起來像這樣:
public class ViewLocator
{
public static readonly string MainPageKey = typeof(MainPage).Name;
public static readonly string WorkPageKey = typeof(WorkPage).Name;
static ViewLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var navigationService = new NavigationService();
navigationService.Configure(MainPageKey, typeof(MainPage));
navigationService.Configure(WorkPageKey, typeof(WorkPage));
SimpleIoc.Default.Register<INavigationService>(() => navigationService);
SimpleIoc.Default.Register<IDialogService, DialogService>();
}
}
之前,這兩個類是在ViewModelLocator合併,但我想通了ViewModelLocator作爲「的ViewModels端 - 的 - 事」部分應該是不知道的意見和它是類型,這就是爲什麼我將該代碼重構爲兩個類。
我MainPageView然後有一個按鈕,這在MainPageView.cs
public class MainPageViewModel : ViewModelBase
{
private INavigationService _navigationService;
public RelayCommand CreateNewImageCommand { get; private set; }
public MainPageViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
CreateNewImageCommand = new RelayCommand(CreateNewImage,() => true);
}
public void CreateNewImage()
{
_navigationService.NavigateTo(Views.ViewLocator.WorkPageKey);
}
}
爲了完整觸發導航命令,這裏是我的App.xaml
<Application
...>
<Application.Resources>
<v:ViewLocator x:Key="ViewLocator" />
<vm:ViewModelLocator x:Key="ViewModelLocator" />
</Application.Resources>
現在什麼碰巧是這樣的:如果我沒有在ViewModelLocator中的DEBUG LINE,在MainPage從ViewModelLocator請求它的ViewModel時,ViewLocator的構造函數尚未被調用,並且return ServiceLocator.Current.GetInstance<MainPageViewModel>();
引發異常。如果我包含DEBUG LINE,這會強制ViewLocator構造函數首先運行,並且一切正常。
如何在沒有奇怪的調試行的情況下實現這種行爲?
我只是要離開這裏[是ServiceLocator反模式](http://stackoverflow.com/questions/22795459/is-servicelocator-anti-pattern) – Liam
TL; DR你應該真的使用依賴注入不服務定位器模式。通常如果從頭開始,這是一個更好,更容易理解的模式。 – Liam
@Liam我不是IoC容器或ServiceLocator的粉絲,也不是你想要調用它的任何東西。這只是我一直在研究如何正確分離虛擬機和V,這是迄今爲止唯一令我滿意的工作方法。然而,我非常願意使用DI - 如果您可以請給我看一些正確使用它的參考代碼。 – Xaser