c# - Silverlight 构造函数注入(inject) View 模型+设计模式

标签 c# silverlight silverlight-4.0 ioc-container mvvm-light

我正在努力掌握在 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/

相关文章:

c# - 如何从 "traditional"过渡到响应式(Reactive) MVVM

c# - 支持字段的自动初始化

c# - 宿主在azure上开发wcf服务

silverlight - 在 SubmitChanges 完成后,DomainContext 有时仍为 HasChanges

wcf - 将 ClaimCollection 从 Silverlight 发送到 WCF

c# - 如何为在套接字上发送的文件创建长度前缀?

c# - 尝试单击按钮登录网站(Httpwebrequest - cookies)

silverlight - 不带Web RTC的Web RTC

c# - Silverlight 中位图和图形(在 Windows 窗体中找到)的等价物是什么?

linq-to-sql - linq to sql 域上下文对域服务类不可见