Использование INotifyChanged на DataContracts - PullRequest
1 голос
/ 25 января 2010

Я пытаюсь отделить фактические данные службы от функциональности службы и поэтому возвращаю данные в виде контракта данных, который содержит несколько свойств (членов данных). Код клиента генерируется с использованием svcutil / edb, который также генерирует реализацию INotifyPropertyChanged для прокси-кода. Насколько мне показало тестирование, этот код не вызывает событие PropertyChanged для изменений, которые произошли на сервере. Кроме того, получение свойства возвращает только значение свойства, как если бы был получен прокси контракта данных.

По сути, вот что у меня есть:

(на стороне сервера)

[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));
    }
}

(на стороне клиента)

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
}

Я ожидаю, что прокси-сервер контракта на данные действует как прозрачный прокси-сервер для контракта на данные сервера, но, похоже, он полностью не связан.

Заранее большое спасибо, Cheers,

Romout

Ответы [ 2 ]

2 голосов
/ 25 января 2010

WCF волшебным образом не генерирует подключения к объектам на стороне сервера. Он просто вызывает любые методы, определенные в вашем ServiceContract, и возвращает данные вам. Другого канала связи нет.

Таким образом, в вашем сценарии вам потребуется дуплексный сервис (см .: http://msdn.microsoft.com/en-us/library/cc645027%28VS.95%29.aspx), который перезванивает клиенту с любыми изменениями с сервера вручную.

1 голос
/ 25 января 2010

Не думайте о DataContract как о «прозрачном прокси», это скорее интерфейс .

То, что два класса реализуют один и тот же интерфейс, не означает, что они делают одно и то же. То же самое верно для клиентской и серверной сторон DataContract.

Клиентская сторона (здесь) генерируется на основе DC, чтобы также включать полезные аспекты DataBinding, такие как INPC и ObservableCollections, вот и все, никакой магии. например, если в объекте на стороне сервера было несколько вычисляемых свойств, эта логика не будет присутствовать на клиенте.

Как уже упоминалось, если вам нужно, чтобы сервер вызывал события на клиенте, вам понадобится какая-то двусторонняя привязка / сервис, другого пути нет (кроме как имитировать его через опрос сервера и т.д ..)

...