我正在构建一个WP7应用程序,通过WCF服务获取所有数据。我想在其中实现MVVM-Light,但是在我已经完成的教程中,我看到在ViewModelLocator中它想要在应用程序启动时创建所有ViewModel的静态实例。 我的问题是,在我的VM的构造函数中,我是在哪里进行WCF调用,结果当然会在回调中返回。它在回调中,我将结果分配给我的视图所见的我的可观察集合。这在没有使用MVVM-Light时工作正常但是如果我实现它我在启动时不能有这些WCF调用,因为它们传递参数未知/可用,直到用户使用应用程序(选择项目等) 我尝试将我对WCF的调用移动到我的可观察集合的getter,但它一直在无限循环中调用WCF。 在我见过的所有MVVM-light示例中,我都没有看到任何人调用WCF服务。 有关将WCF调用放在模型中的位置的任何建议吗?
答案 0 :(得分:2)
与MVVM一样,没有正确的方式......因为它是关于feedom ... :-)
如果需要,您可以将代码放入视图模型中。但是,您还必须在视图模型中生成设计时数据 - 如果要使用它。
这种方法的一大缺点是您在视图模型和服务代码之间引入了耦合(因为您必须在视图模型中实例化服务)。解组件的一般方法是创建一个描述服务的接口,并将实现此接口的对象实例注入到其构造函数的视图模型中。这使您可以创建设计时间和运行时实现,并且您的视图模型不关心它使用哪一个 - 即对象是分离的。
修改强>
在我的帖子中注入并不暗示您使用注入容器/框架,它只意味着您使用接口来抽象服务行为,然后将实现者或此接口传递给视图模型的构造函数。您现在可以在创建视图模型时传递界面的不同实现,例如在视图定位器中。
建议的模式称为“控制反转”,注入是一种将在别处创建的对象传递到您创建的类中的技术。通过这个,你的班级现在可以免于执行者的任何细节知识,并且它们可以互换。
控制容器的反转 - 比如ninject,unity等 - 只是帮助你自动解析依赖关系,但它们不是必需的用于使用in版本的控制模式。
答案 1 :(得分:1)
我认为在ViewModel中放置WCF调用并不好,您应该将WCF调用封装在另一个类中。您的ViewModel应该只包含GUI逻辑。我认为你从WCF调用获得的是模型,你可以使用模型来创建ViewModel。
答案 2 :(得分:1)
以下是我的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
}
});