【发布时间】:2016-06-22 07:59:09
【问题描述】:
我正在开发一个使用由服务器应用程序 (WPF) 托管的 WCF 服务的 MVVM WPF 应用程序。我有一些疑问,知道哪种方式是使用服务的最佳方式:
- 服务的InstanceContextMode设置为Single
- WCF 服务使用 duplex 合同和 回调
- MainWindow 定期调用服务的“Ping”方法来了解(并以图标直观地显示)服务是否可用。 MainWindow 实现了一个 PingReply 回调来获取回复。
- MainWindow 有一个Frame 用于加载不同的Pages。每个 Page 都包含多个 UserControl,它们调用服务来更新他们的视图。
这里是简化的服务接口ISrvService.cs
[ServiceContract(CallbackContract = typeof(ISrvServiceCallback))]
public interface ISrvService
{
[OperationContract(IsOneWay = true)]
void Ping();
[OperationContract(IsOneWay = true)]
void GetUserControlAStatus();
[OperationContract(IsOneWay = true)]
void GetUserControlBStatus();
}
public interface ISrvServiceCallback
{
[OperationContract(IsOneWay = true)]
void PingReply(string reply);
[OperationContract(IsOneWay = true)]
void GetUserControlAReply(string reply);
[OperationContract(IsOneWay = true)]
void GetUserControlAReply(string reply);
}
这样当我在MainWindow中实现ISrvServiceCallback接口有PingReply回调时,我还需要实现GetUserControlAReply em> 和 GetUserControlBReply (现在我只是在没有代码的情况下实现它们)
MainWindow.xaml.cs 中的GetUserControlAReply
public void GetUserControlAReply(string reply)
{
//nothing to do
}
当我在 UserControlA 的模型中实现 ISrvServiceCallback 接口时也会发生同样的事情:我必须在没有代码的情况下实现 PingReply。
我认为这不是一个好的工作方式。解决此类问题的最佳实践是哪些?你能给我推荐一些关于这种情况的教程吗?
编辑 正如@lokusking 所建议的,我提供了UserControl 示例的Model 和ViewModel。 View 绑定到 ViewModel 的 LblStatus。
UserControlAModel.cs
public class UserControlAModel: INotifyPropertyChanged, SrvService.ISrvServiceCallback
{
System.ServiceModel.InstanceContext instanceContext;
SrvService.SrvServiceClient client;
public event PropertyChangedEventHandler PropertyChanged;
private string _Status;
public string Status
{
get { return _Status; }
set { _Status = value; NotifyPropertyChanged(); }
}
public UserControlAModel()
{
Status = "NOT CONNECTED";
}
public void GetStatus()
{
instanceContext = new System.ServiceModel.InstanceContext(this);
client = new SrvService.SrvServiceClient(instanceContext);
client.GetUserControlAStatus();
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//callbacks implementation
public void GetUserControlAReply(string reply)
{
Status = reply;
}
public void GetUserControlBReply(string reply)
{
//nothing to do
}
public void PingReply(string reply)
{
//nothing to do
}
}
UserControlAViewModel.cs
public class UserControlAViewModel : INotifyPropertyChanged
{
private UserControlAModel _uControlAModel;
public UserControlAModel MyUserControlAModel
{
get
{ return _uControlAModel; }
set
{ _uControlAModel = value; NotifyPropertyChanged(); }
}
public string LblStatus
{
get { return MyUserControlAModel.Status; }
set { MyUserControlAModel.Status = value; NotifyPropertyChanged(); }
}
public UserControlAViewModel()
{
MyUserControlAModel = new UserControlAModel();
MyUserControlAModel.PropertyChanged -= UserControlAModel_PropertyChanged;
MyUserControlAModel.PropertyChanged += UserControlAModel_PropertyChanged;
MyUserControlAModel.GetStatus();
}
private void UserControlAModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyPropertyChanged(string.Empty);
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
【问题讨论】: