2009-08-26 14 views
7

Pregunta en el título ... En resumen: tengo un servicio WCF que expone operaciones que devuelven clases de entidad. Las clases del lado del cliente heredan de una clase base abstracta en lugar del System.Object predeterminado. La clase base abstracta tiene un constructor predeterminado definido. Al llamar a uno de los métodos de servicio, esperaría que se llamara al constructor cuando el serializador de contratos de datos materializara los objetos devueltos. Sin embargo, el constructor no es llamado. Si, por otro lado, creo una instancia de la clase de entidad yo mismo, entonces se llama al constructor de la clase abstracta.¿Por qué no se llama al constructor de mi clase base abstracta cuando el deserializador de WCF inicializa un objeto?

¿Por qué, oh por qué, y hay una solución? ¿O me perdí algo? ¿Hay otra firma de constructor que el serializador de datacontract llama cuando materializa objetos? Si no es así, ¿cómo puede el serializador de contratos de datos materializar objetos sin llamar a los constructores de la misma manera que una llamada "nueva SomeClass()"? ¿O tomé demasiado café hoy (solo tuve 2 o 3 tazas hasta ahora)?

Respuesta

11

WCF (y DataContractSerializer en particular) no utiliza constructores. No, realmente (usa FormatterServices.GetUninitializedObject para crear objetos sin formato).

Se espera que todos los datos se inicialicen mediante el serializador o campos no serializados, mediante devoluciones de llamadas de serialización que se agregan (por ejemplo, a través de [OnDeserialized]).

+1

Gracias por la respuesta rápida. Guau. Eso me sorprende Pensé que la inicialización de todos los objetos daría como resultado el llamado de constructores. Oh, bueno, aprendí algo nuevo hoy ... :) – KristoferA

+0

De hecho, es bastante sorprendente. ¡Tuve que cavar en un reflector la primera vez que lo vi! –

+0

Una pregunta de seguimiento [por curiosidad] sería: _ ¿por qué lo hicieron de esa manera? ¿Actuación? Para meterse con nuestras cabezas? ¿O alguna otra razón mejor? :) – KristoferA

1

Entiendo completamente las razones, sin embargo, no entiendo por qué no admiten las devoluciones de llamadas de serialización en Silverlight. Me parece que en una comunicación WCF - Silverlight no puedo inicializar mi contrato de datos sin hackearme. Por lo tanto, si tuviera un miembro privado en mi clase base para uso interno (. Ej comportamiento deshacer-rehacer), no puede utilizar el constructor por defecto:

Stack<PropertyChange> UndoStack = new Stack<PropertyChange>(); 

Esto simplemente no funciona. Para que funcione, debería escribir algo como esto:

Stack<PropertyChange> _UndoStack; 
Stack<PropertyChange> UndoStack 
{ 
    get 
    { 
      return _UndoStack == null ? (_UndoStack = new Stack<PropertyChange>()) : _UndoStack; 
    } 
} 

Parece una solución para mí. Alguien tiene mejores ideas?

+0

Esto parece una solución, pero debes asegurarte de que no haya una condición de carrera entre el cheque nulo y el colocador o de lo contrario puedes devolver un Stack Stack por un hilo. La única forma que conozco de resolver esto es al menos usar OnDeserializing, crear un 'object syncRoot = new object()' y bloquearlo en el getover de UndoStack (o directamente crear la instancia de UndoStack en este método. – eFloh

Cuestiones relacionadas