我试图掌握在Silverlight中编写可测试的viewmodels 4. Im目前使用MVVM灯.
我使用AutoFac和IoCContainer正在做它的工作.但是要注入viewmodel的构造函数,它们绑定到Views,我有这个构造函数链接:
public Userviewmodel() : this(IoCContainer.Resolve<IUserServiceAsync>()) { } public Userviewmodel(IUserServiceAsync userService) { if (this.IsInDesignMode) return; _userService = userService; }
哪个不舒服,但是我到目前为止找到的最好的选择.这个工作和我的应用程序按照需要工作,并且可以通过控制进行测试.
但是,我的VM对我的看法是这样的:
<UserControl.DataContext> <viewmodel:Userviewmodel /> </UserControl.DataContext>
在我的XAML页面属性中,VS2010和Blend中的设计模式都不起作用.
有没有更好的方法来实现在Silverlight中尝试使用设计模式的工具?失去设计模式不是一个交易破产者,但在学习XAML时会很方便.一个更清洁的无链接的方式将是很好,虽然!
我认为可能使用AutoFac / IoC来解析视图模式,如同上面提到的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 -->
您可以使您的模拟视图模型定位器返回Blend使用的安全易读的数据,并且在运行时您将使用您的真实服务.
这样你就不会丢失设计时间数据,并且您不必在视图模型中牺牲依赖注入方法的清洁度.
我希望这有帮助.