Понимание ServiceKnownType в WCF
У меня есть небольшая проблема с пониманием ServiceKnownType в WCF.
Взятый из этот блог, следующий код не работает:
[DataContract(Namespace = "http://mycompany.com/")]
public class Shape{…}
[DataContract(Namespace = "http://mycompany.com/")]
public class Circle : Shape {…}
[ServiceContract]
public interface IMyServer
{
[OperationContract]
bool AddShape(Shape shape);
}
.
IMyServer client = new ChannelFactory<IMyServer>(binding, endPoint).CreateChannel();
client.AddShape(new Circle());
Причина, по которой он не работает, заключается в том, что вы пытаетесь добавить круг, но servicecontract допускает только Shape. Вы должны что-то делать с известными типами, но я немного смущен тем, как это работает.
Поскольку этот код находится в сервисе, почему он не знает автоматически, что Circle получен из Shape? Кроме того, что действительно делает ServiceKnownType?
Когда ServiceKnownType помещается под DataContract, очевидно, что он работает. Я предполагаю, что он говорит, что этот тип объекта, называемый Shape, также может быть кругом. У меня возникли проблемы с пониманием того, почему это будет сделано так, потому что если вы добавите новый тип типа Square, вам придется добавить к классу Shape класс ServiceKnownType. Разве это не имело бы смысла, если бы он не мог этого сделать, чтобы положить KnownType на квадрат, а не в форму? Итак, Квадрат говорит, что я - Форма, и вам не нужно возиться с классом Shape? Если ваш класс Shape встроен в библиотеку, и вы хотите создать свою собственную тупиковую форму, такую как DiamondShape, вы не можете добавить ее в класс Shape, потому что у вас нет доступа к исходному коду.
Ответы
Ответ 1
Проблема в том, что WCF не входит во все сборки и пытается найти все возможные подтипы Shape. Он также не передает информацию о типе (сборка, полное имя типа) с XML-документом.
Итак, хотя было бы не проблемой генерировать тег "Circle" в исходящем XML, входящий десериализатор не знал бы, что с этим делать.
"Хак" KnownType похож на реестр известных типов, который должен быть реализован обеими сторонами. Это явное. В этом реестре десериализатор знает, что "Круг" десериализует тип X без каких-либо проблем и без необходимости анализировать все доступные или доступные сборки для производных типов.
Помните, что Square не говорит "Я форма", это как тег XML, и из этого вам нелегко и автоматически знать, какой .NET-класс использовать.