【问题标题】:MVVM-Light: Where to put WCF call in ViewModelMVVM-Light:在 ViewModel 中放置 WCF 调用的位置
【发布时间】:2011-07-30 21:18:54
【问题描述】:

我正在构建一个通过 WCF 服务获取其所有数据的 WP7 应用程序。我想在其中实现 MVVM-Light,但在我完成的教程中,我看到在 ViewModelLocator 中它想在应用程序启动时创建我所有 ViewModel 的静态实例。 我的问题是,在我的 VM 的构造函数中,我进行 WCF 调用,结果当然会在回调中返回。在回调中,我将结果分配给我的视图看到的可观察集合。这在不使用 MVVM-Light 时工作正常,但如果我实现它,我无法在启动时进行这些 WCF 调用,因为它们传递未知/可用的参数,直到用户使用应用程序(选择项目等) 我尝试将我对 WCF 的调用移动到我的 observable 集合的 getter,但它一直在无限循环中调用 WCF。 在我见过的所有 MVVM-light 示例中,我没有看到有人调用 WCF 服务。 关于将我的 WCF 调用放在模型中的什么位置有什么建议吗?

【问题讨论】:

    标签: wcf mvvm-light


    【解决方案1】:

    和以往一样,在 MVVM 中没有 正确的 方式 ... 因为它是关于 feedom ... :-)

    您可以根据需要将代码放入您的视图模型中。但是,如果您想使用它,您还必须在视图模型中生成设计时数据。

    这种方法的最大缺点是您在视图模型和服务代码之间引入了耦合(因为您必须在视图模型中实例化服务)。解耦组件的一般方法是创建一个描述您的服务的接口,并在其构造函数中将实现此接口的对象的实例注入到您的视图模型中。这使您能够创建设计时和运行时实现,并且您的视图模型不关心它使用哪一个 - 即对象是解耦的。

    编辑

    在我的帖子中注入并不意味着您使用注入容器/框架,它仅意味着您使用一个接口来抽象您的服务行为,然后将一个实现者或这个接口传递给视图模型的构造函数。您现在可以在创建视图模型时传递接口的不同实现,例如在视图定位器中。

    建议的模式称为“控制反转”,注入是一种将在别处创建的对象传递到您创建的类的技术。通过这一点,您的我们的类现在可以不受实现者的任何详细知识的影响,并且它们可以互换。

    控制容器的反转——如ninject、unity等——只是帮助你自动解决依赖关系,但是,它们不是必需的使用控制模式的版本。

    【讨论】:

    • 感谢您的回复。我喜欢你的想法,但由于最近使用 Ninject 的经验,我发现我的注射技能有点不成熟。我得回去了。现在我实现了一个停止间隙,它从绑定到页面 Loaded 事件的命令调用服务。解决了我的问题,但我更喜欢你的声音。几周前我看到一篇文章讨论了像你的想法这样的实现,我希望我知道我在哪里看到它。如果您有参考资料,我将有兴趣看到它。感谢您的宝贵时间。
    • 查看关于控制模式版本和控制容器版本关系的编辑。
    【解决方案2】:

    我认为将 WCF 调用放在 ViewModel 中不好,您应该将 WCF 调用封装在另一个类中。您的 ViewModel 应该只包含 GUI 逻辑。我认为你从 WCF 调用中得到的是模型,你可以使用模型来创建 ViewModel。

    【讨论】:

      【解决方案3】:

      这是我的 CommonServiceHelper.cs 文件的示例

         public void GetUserSettings(UserInfoIn input, Action<UserInfoOut, Exception> callback)
          {
              var proxy = new CommonServiceClient();
      
              try
              {
                  proxy.GetUserSettingsCompleted += (sender, eventargs) =>
                  {
                      var userCallback = eventargs.UserState as Action<UserInfoOut, Exception>;
                      if (userCallback == null)
                          return;
      
                      if (eventargs.Error != null)
                      {
                          userCallback(null, eventargs.Error);
                          return;
                      }
                      userCallback(eventargs.Result, null);
                  };
                  proxy.GetUserSettingsAsync(input, callback);
              }
              catch (Exception ex)
              {
                  proxy.Abort();
                  //ErrorHelper.WriteErrorLog(ex.ToString());
              }
              finally
              {
                  if (proxy.State != CommunicationState.Closed)
                  {
                      proxy.CloseAsync();
                  }
              }
          }
      

      然后在 ViewModel 我这样称呼它:

                     var serviceCommon = new CommonServiceHelper();
                                  serviceCommon.GetUserSettings(userSettingsInput, (result, error) =>
                                  {
                                      if (result != null && error != null)
                                      {
                                          //everything is ok
                                      }
                                      else
                                      {
                                          //handle errors
                                      }
                                  });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多