2

我可能做错了,但我认为我走在正确的道路上。我是第一次构建 WPF 应用程序,但我仍然习惯了一些事情的完成方式。

我的想法

  • 我的目标是让我的 ViewModel 类更具可测试性。
  • ViewModel 依赖于一个服务类,没有它就无法运行。
  • 因此,将服务注入 ViewModel 对我来说似乎是有意义的,这样我也可以开始模拟它以进行测试。

我做了什么

  • 对我的视图模型进行了 XAML 引用,称为“UploaderViewModel”:
 <Window.DataContext>
     <viewModels:UploaderViewModel>
         </viewModels:UploaderViewModel>
 </Window.DataContext>

注意:在我尝试进行注射之前,这很好用

  • 在我的 app.xaml.cs 文件中设置结构映射:
   void App_Startup(object sender, StartupEventArgs eventArgs)
    {
        ContainerBootstrapper.BootstrapStructureMap();
        ProcessStartupArguments(eventArgs);
    }

这调用了我的引导程序类:

public static class ContainerBootstrapper
{
    public static void BootstrapStructureMap()
    {
        ObjectFactory.Initialize(
            x => x.For<IVEDocumentService>().Use<VEDocumentService>()
            );
    }
}
  • 然后我让我的 UploaderViewModel 类将 IVEDocumentService 作为构造函数参数:

    public UploaderViewModel(IVEDocumentService documentService)
    {
        _documentService = documentService;
        //other unrelated code below this
     }
    

怎么了

我收到一个 XAML 错误,指出没有为 ViewModel 找到默认构造函数,这是有道理的,因为我没有UploaderViewModel(), 只有UploaderViewModel(IVEDocumentService documentService).

问题

  • 解决此问题的最佳方法是什么?
  • 我应该创建一个 UploaderViewModel() 构造函数并使 StructureMap 使用服务实例调用 UploaderViewModel,还是有更好的方法?

更新 1 - 尝试使用资源字典,StructureMap 错误。

基于this SO Answer to a similar question,我尝试了:

  • 更新我的 App_Startup 以将 UploaderViewModel 的实例添加到资源字典中:
void App_Startup(object sender, StartupEventArgs eventArgs)
{
  ContainerBootstrapper.BootstrapStructureMap();

var uploaderViewModel = new UploaderViewModel(new Container().GetInstance<IVEDocumentService>());
Current.Resources["UploaderViewModel"] = uploaderViewModel;

ProcessStartupArguments(eventArgs);

}
  • 添加DataContext="{StaticResource UploaderViewModel}"到我的<Window>声明中
  • 注释掉我的<viewModels:UploaderViewModel/>声明

执行此操作后,StructureMap 现在会引发错误:

“StructureMap 异常代码:202No Default Instance defined for PluginFamily

4

1 回答 1

1

我想到了。我想我没有正确配置静态资源。使用 StructureMap 的解决方案是执行以下操作:

应用程序.xaml.cs

   void App_Startup(object sender, StartupEventArgs eventArgs)
    {
        ContainerBootstrapper.BootstrapStructureMap();
        //Other logic
     }

ContainerBootstrapper 类

public static void BootstrapStructureMap()
{
    ObjectFactory.Initialize(x => x.For<IVEDocumentService>().Use<VEDocumentService>());
}

主窗口.xaml.cs

我将资源创建移到了这个类中:

public MainWindow()
{
    var uploaderViewModel = new UploaderViewModel(ObjectFactory.GetInstance<IVEDocumentService>());
    this.Resources["UploaderViewModel"] = uploaderViewModel;
    InitializeComponent();
}

主窗口.xaml

<Window>定义上,我设置了DataContext="{StaticResource UploaderViewModel}".

奇迹般有效。我相信这是没有在适当的范围(窗口)绑定资源的组合。

于 2013-08-05T15:40:56.197 回答