Как использовать KnownType, чтобы включить полиморфные возвращаемые значения в контракте службы WCF? - PullRequest
3 голосов
/ 01 декабря 2009

Я преобразовываю интерфейс удаленного взаимодействия в WCF, однако у меня есть метод, который объявлен как возвращающий «объект» и может возвращать несколько различных типов (в основном различные перечисления)

Где найти пример, как справиться с этим?

(Я использую сборку общего контракта, которая содержит все типы, а не генерацию клиентского прокси, если это имеет значение.)

Ответы [ 5 ]

1 голос
/ 01 декабря 2009

Взгляните на это KnownTypeProvider Мы используем это для соединений silverlight и используем NetDataContractSerializer, когда мы совместно используем одни и те же сборки между клиентом и сервером.

1 голос
/ 01 декабря 2009

Что ж, документация содержит пример использования KnownTypeAttribute. Обратите внимание, что он допускает несколько атрибутов в одном классе, поэтому вы можете идентифицировать более одного полиморфного дочернего типа.

Это довольно ограниченная функциональность, поскольку она позволяет указывать только типы, известные во время разработки, поэтому она не вписывается в мышление расширяемости и удобства обслуживания, которое обычно заставляет нас использовать полиморфизм.

AFAIR, это ограничение существует главным образом из-за ограничений в WSDL / XSD, на которые часто переводятся контракты WCF. Мы всегда должны помнить, что только 10000 * сообщений перемещаются по проводам, а не объектов . Клиент на другом конце может вообще не быть приложением .NET, поэтому для обеспечения совместимости мы должны принять эти ограничения.

Я обычно нахожу, что более статичный редизайн интерфейса сервиса часто является лучшим решением. Вы также можете рассмотреть возможность представления возвращаемого типа как System.Object, который будет переводиться в xs: any, но, очевидно, по пути вы потеряете безопасность типов.

WCF имеет расширенную опцию, которая позволяет вам делиться типами между сервером и клиентом, так что это также может быть решением для вас. Однако, если вы сделаете это, вы потеряете функциональную совместимость и множество других достоинств, поэтому тщательно обдумайте этот вариант, прежде чем выбрать его.

0 голосов
/ 04 февраля 2011

Выпуск MSDN Magazine за февраль 2011 года содержит « Известные типы и универсальный резольвер », который показывает хорошее решение этой проблемы.

0 голосов
/ 04 декабря 2009

Это то, что я сделал в конце, однако я схожу начать использовать один из решений, которые Аарон Фишер дал в долгосрочной перспективе.

/// <summary>
/// WCF can not cope with a method that returns an object so wrap the
/// untyped object in a typed object.  Then use KnowType to tell WCF 
/// about the typs that are wrapped
/// </summary>
[DataContract(), KnownType(typeof(MyType1)), KnownType(typeof(MyType2))]
public class UntypedObjectHolder
{
    [DataMember()]
    private object m_Value;

    public UntypedObjectHolder(object value)
    {
        m_Value = value;
    }

    public object Value
    {
        get { return m_Value; }
    }
}

Тогда в моем интерфейсе

[OperationContract()]
UntypedObjectHolder GetValue(eGetValueType valueType);

Другой вариант, который может работать, но я не пробовал:

[ServiceContract]
[ServiceKnownType(typeof(PhotoCamera))]
[ServiceKnownType(typeof(TemperatureSensor))]
[ServiceKnownType(typeof(DeviceBase))]
public interface IHomeService
{    
   [OperationContract] IDevice GetInterface();
}
0 голосов
/ 01 декабря 2009

Я не уверен, что KnowType attr будет работать с перечислениями, поскольку они не могут наследоваться?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...