我正在努力掌握在 Silverlight 4 中编写可测试的 ViewModel。我目前正在使用 MVVM light。
我使用的是 AutoFac,而 IoCContainer 工作正常。然而,为了注入(inject)绑定(bind)到 View 的 ViewModels 的构造函数,我有这个构造函数链接:
public UserViewModel() : this(IoCContainer.Resolve<IUserServiceAsync>())
{
}
public UserViewModel(IUserServiceAsync userService)
{
if (this.IsInDesignMode) return;
_userService = userService;
}
虽然感觉不干净,但却是目前为止我找到的最佳选择。这有效,我的应用程序按预期工作,并且可以通过反转控制进行测试。
但是,我的 VM 像这样绑定(bind)到我的 View :
<UserControl.DataContext>
<ViewModel:UserViewModel />
</UserControl.DataContext>
在我的 XAML 页面属性中,VS2010 和 Blend 中的设计模式都不起作用。
是否有更好的方法来实现我在 Silverlight 中尝试的仍然适用于设计模式的内容?丢失设计模式不会破坏交易,但在学习 XAML 时会很方便。不过,更干净的非链接方式会很好!
我认为可以使用 AutoFac/IoC 将 View 模型解析为 View ,与上面的 XAML 标记方法相反,然后沿着这条路走下去?
谢谢。
最佳答案
我建议您实现一个 ViewModelLocator,而不是实现第一个构造函数,如下所示:
public class ViewModelLocator
{
IoCContainer Container { get; set; }
public IUserViewModel UserViewModel
{
get
{
return IoCContainer.Resolve<IUserViewModel>();
}
}
}
然后在 XAML 中将定位器声明为静态资源:
<local:ViewModelLocator x:Key="ViewModelLocator"/>
当您初始化应用程序时,有必要为定位器提供容器实例:
var viewModelLocator = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
if(viewModelLocator == null) { // throw exception here }
viewModelLocator.Container = IoCContainer;
然后在 XAML 中您可以干净地使用资源:
<UserControl
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
对于设计时间,您可以实现 MockViewModelLocator:
public class MockViewModelLocator
{
public IUserViewModel UserViewModel
{
get
{
return new MockUserViewModel();
}
}
}
在 XAML 中适本地声明它:
<local:MockViewModelLocator x:Key="MockViewModelLocator"/>
最后在您的用户控件中使用它:
<UserControl
d:DataContext="{Binding Path=UserViewModel, Source={StaticResource MockViewModelLocator}}"
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
您可以让您的模拟 View 模型定位器返回安全且易于阅读的数据以供 Blend 使用,并且在运行时您将使用您的真实服务。
这样您就不会丢失设计时数据,也不必牺牲 View 模型中依赖注入(inject)方法的简洁性。
希望对您有所帮助。
关于c# - Silverlight 构造函数注入(inject) View 模型+设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4033600/