2010-05-03 9 views
10

Tengo problemas para entender ServiceKnownType en WCF.Descripción de ServiceKnownType en WCF

Tomado de this blog, el código siguiente no funciona:

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

La razón por la que no funciona es porque se está intentando añadir un círculo, pero el ServiceContract sólo permite una forma. Se supone que debes hacer algo con los tipos de conocimiento, pero estoy un poco confundido acerca de cómo funciona eso.

Dado que el código está en el servicio, ¿por qué no se sabe automáticamente que un círculo se deriva de la forma? Además, ¿qué hace ServiceKnownType en realidad?

Cuando ServiceKnownType se pone debajo de la DataContract, al parecer, que hace que funcione. Supongo que dice que bueno, este tipo de objeto particular llamado Forma también puede ser un Círculo. Tengo problemas para entender por qué lo haría de esta manera, porque si agrega un tipo nuevo como Square, tendrá que agregar a la clase Shape un ServiceKnownType para él. ¿No tendría sentido si no puede inferirlo, poner KnownType en el cuadrado en lugar de la forma? Entonces el Cuadrado dice "hey, yo soy una Forma", ¿y no tienes que jugar con la clase Shape? Si su clase Shape está integrada en una biblioteca y desea crear su propia forma dervied como DiamondShape, no puede agregarla a la clase Shape porque no tiene acceso al código fuente.

Respuesta

12

El problema es que WCF no entra en todas las asambleas y trata de encontrar todos los subtipos posiblemente de forma. Tampoco transmite la información de tipo (conjunto, nombre de tipo totalmente calificado) con el documento XML.

Entonces, si bien no sería un problema generar una etiqueta "Círculo" en el XML saliente, el deserializador entrante no sabría qué hacer con esto.

KnownType "hack" es como un registro de tipos conocidos que debe ser implementado por ambas partes. Es explícito Con este registro, el deserializador sabe que "Círculo" se deserializa al tipo X, sin ninguna posibilidad de ambigüedad y sin tener que analizar todos los conjuntos disponibles o accesibles para los tipos derivados.

Recuerde, Square no dice "Soy una forma", viene como una etiqueta XML y de eso no se puede saber fácil y automáticamente qué clase .NET usar.

+0

¿No tiene que examinar los DataContracts para ese servicio? Solo hay dos en ese ejemplo y probablemente los almacenó en caché de todos modos. – NibblyPig

+0

No, porque el contrato de datos no indica qué subclases son realmente válidas para esa posible llamada, o cuáles existen. el contrato de datos solo dirá "ok, esta es una forma en esta propiedad" y no "qué subclases de acción están viniendo aquí". – TomTom