Jam*_*min 10 c# silverlight ioc-container silverlight-4.0 mvvm-light
我试图在Silverlight 4中编写可测试的ViewModel.我正在使用MVVM灯.
我正在使用AutoFac和IoCContainer正在完成它的工作.但是要注入ViewModel的构造函数,它绑定到Views我有这个构造函数链接:
public UserViewModel() : this(IoCContainer.Resolve<IUserServiceAsync>())
{
}
public UserViewModel(IUserServiceAsync userService)
{
if (this.IsInDesignMode) return;
_userService = userService;
}
Run Code Online (Sandbox Code Playgroud)
哪个不干净,但是到目前为止我找到的最佳选择.这是有效的,我的应用程序可以根据需要工作,并且可以通过控制倒置来测试
但是,我的VM绑定到我的视图,如下所示:
<UserControl.DataContext>
<ViewModel:UserViewModel />
</UserControl.DataContext>
Run Code Online (Sandbox Code Playgroud)
在我的XAML页面属性中,VS2010和Blend中的设计模式都不起作用.
是否有更好的方法来实现我在Silverlight中尝试仍然适用于设计模式的东西?丢失设计模式不是一个交易破坏者,但在学习XAML时会很方便.一个更干净的无链接方式会很好!
我认为可以使用AutoFac/IoC将视图模型解析为视图,与上面的XAML标记方法一致,并沿着这条路线走下去?
谢谢.
Mur*_*ven 10
我建议你实现一个ViewModelLocator,而不是实现第一个构造函数,如下所示:
public class ViewModelLocator
{
IoCContainer Container { get; set; }
public IUserViewModel UserViewModel
{
get
{
return IoCContainer.Resolve<IUserViewModel>();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在XAML中将定位器声明为静态资源:
<local:ViewModelLocator x:Key="ViewModelLocator"/>
Run Code Online (Sandbox Code Playgroud)
在初始化应用程序时,必须为定位器提供容器的实例:
var viewModelLocator = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
if(viewModelLocator == null) { // throw exception here }
viewModelLocator.Container = IoCContainer;
Run Code Online (Sandbox Code Playgroud)
然后在XAML中,您可以干净利用资源:
<UserControl
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
Run Code Online (Sandbox Code Playgroud)
在设计时,您可以实现MockViewModelLocator:
public class MockViewModelLocator
{
public IUserViewModel UserViewModel
{
get
{
return new MockUserViewModel();
}
}
}
Run Code Online (Sandbox Code Playgroud)
适当地在XAML中声明它:
<local:MockViewModelLocator x:Key="MockViewModelLocator"/>
Run Code Online (Sandbox Code Playgroud)
最后在用户控件中使用它:
<UserControl
d:DataContext="{Binding Path=UserViewModel, Source={StaticResource MockViewModelLocator}}"
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
Run Code Online (Sandbox Code Playgroud)
您可以使模拟视图模型定位器返回安全且易于读取的数据供Blend使用,并且在运行时您将使用您的真实服务.
这样您就不会丢失设计时数据,也不必牺牲视图模型中依赖注入方法的清洁度.
我希望这有帮助.