Using INotifyChanged on DataContracts
I'm trying to separate actual service data from service functionality and am therefore returning data as a data contract which holds several p开发者_如何学Pythonroperties (data members). The client code is generated using svcutil /edb which also generates an INotifyPropertyChanged implementation for the proxy code. As far as my testing revealed, that code does not invoke the PropertyChanged event for changes which happened on the server. Additionally, getting a property does only return the property value as when the data contract proxy has been obtained.
Basically, here is what I've got:
(Server Side)
[ServiceContract]
public interface IControllerService
{
[OperationContract]
DataModel GetDataModel();
}
[DataContract]
public class DataModel : INotifyPropertyChanged
{
private string _state;
[DataMember]
public string State
{
set
{
if (_state != value)
{
_state = value;
OnPropertyChanged("State");
}
}
get
{
return _state;
}
}
public event PropertyChangedEventHandler PropertyChanged;
[OperationContract]
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
(Client Side)
private void Test()
{
ControllerServiceClient client = new ControllerServiceClient();
DataModel model = client.GetDataModel();
model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(DataModelChanged);
Console.WriteLine(model.State);
// ... invoke something that forces the server to change the data model
// Output stays the same
Console.WriteLine(model.State);
}
private void DataModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// This method never get called for server-side changes
}
I expect that the data contract proxy acts as a transparent proxy to the server's data contract but it seems to be completely unbound.
Thanks very much beforehand, Cheers,
Romout
WCF does not magically generate hookups to the server side objects. It simply calls whatever methods are defined in your ServiceContract and returns the data to you. There is no other communication channel beyond that.
So in your scenario you would need a duplex service (see: http://msdn.microsoft.com/en-us/library/cc645027%28VS.95%29.aspx) that calls back to the client with any change from the server manually.
Don't think of the DataContract as a 'transparent proxy,' it's more of an interface.
Just because two classes implement the same interface, it doesn't mean they do exactly the same thing. The same is true for the client and server sides of the DataContract.
The client-side (here) is generated based on the DC, to also include DataBinding-helpful aspects, like INPC and ObservableCollections, that's it, no magic. eg if there were some calculated properties on your server-side object, that logic will not be present on the client.
As has been mentioned, if you have a need for the server to invoke events on the client, you'll need some kind of two-way binding/service, there's no other way (other than simulating it via polling the server, etc..)
精彩评论