2010-02-23 18 views
5

Tengo el siguiente método que toma un objeto de detalles, lo valida, lo convierte en una solicitud y lo pone en cola. Todo está bien, aparte de la solicitud de validación con la que estoy teniendo problemas. Básicamente, existe una lógica de validación diferente para cada objeto de detalles diferentes. Sé por la restricción genérica que el objeto de detalles debe tener una clase base de BaseDetails y del parámetro genérico real sé el tipo derivado exacto, pero no sé cómo usarlos para escribir mi clase de validador para que maneje todos los tipos de detalles :Pregunta de polimorfismo novato usando genéricos

private void Enqueue<TDetails, TRequest>(TDetails details) 
    where TDetails: BaseDetails where TRequest: BaseRequest 
{ 
    bool isValid = _validator.Validate(details); 

    if (isValid) 
    { 
    TRequest request = ObjectMapper 
     .CreateMappedMessage<TDetails, TRequest>(details); 

    _queue.Enqueue(request); 
    } 
} 
+0

¿Necesita una validación diferente para cada implementación de TDetails? –

+0

sí, algo de esto es común, pero hay diferentes bits adicionales para cada TDetails. –

Respuesta

0

Creo que necesita crear una clase de validador para cada implementación de TDetails que sepa cómo validar esa implementación en particular, luego tener una fábrica para producir el validador correcto para una implementación de TDetails determinada y hacer que su _validator obtenga la clase correcta para haciendo el trabajo de fábrica y haciendo que la clase haga la validación.

Obviamente, podría tener algo de la validación común en una clase base.

Usted podría ser mejor tener la validación en el objeto en sí, aunque en lugar de crear un validador independiente para cada aplicación TDetails ...

+0

Re: la fábrica - ¿cómo se definiría esto?Cada validador tendría una firma de método diferente, ya que tomaría un tipo diferente, o ¿los declararía todos para tomar en la clase base y luego los convertiría al tipo derivado en cada método de validación? –

+0

la fábrica tendría un método 'IDetailsValidator GetValidator (TDetails)' y luego haría un 'interruptor (typeof (TDetails))' y luego para cada caso devuelve una implementación de esa interfaz. esta interfaz tendría un método 'bool IsValid (TDetails)'. Cada implementación arrojaría al tipo correcto en el método y realizaría la validación. –

+0

no puede alejarse del gran interruptor (o si no más) construir, por lo que es una buena idea tenerlo en un solo lugar (la clase de fábrica) donde puede ir a agregar nuevos validadores a medida que son escrito, en lugar de tener que hacer el cheque en varios lugares en su código. –

2

Sólo significa que debe haber una jerarquía correspondiente de validadores, cada uno unido a su propia TDetails objeto. Como TDetails es siempre BaseDetails, debe especificar manualmente qué clase secundaria admite y ejecutar cadena en un validador anidado.

1

Para mí, parece que la lógica de validación debe atribuirse a los detalles propios objetos (si es posible , por supuesto). Luego, puede marcar el resumen de la clase base y anular el método Validate para las clases de detalles específicos si es necesario.

Por otro lado, 'composición sobre herencia' está de moda en este momento.

+0

Eso sería más fácil, pero TDetails son contratos de datos de WCF y no tengo permitido tocarlos. –

+0

, entonces parece que está atascado con un validador por TDetails. Solo esperemos que tenga el control de las implementaciones de TDetails ... –

+0

@Stacey Entonces usaría el contenedor de inyección de dependencia para pasar el validador necesario (base o detalles derivados de clase específica). Del mismo modo que en el patrón de repositorio ampliamente aceptado. –

1

Sé por la restricción genérica que los detalles del objeto debe tener una clase base de BaseDetails

Esto se conoce en proceso de compilación de código de bytes (me refiero Visual Studio sabe)

y desde el parámetro genérico real sé que el tipo exacto derivado

Pero esto sólo se conoce faet r Compilación JIT (Visual Studio no sabe nada al respecto). Es como un enlace tardío.

Así que si quiere escribir una clase de validador con varios métodos con diferentes tipos de argumentos, no puede hacer esto, porque el compilador de Visual Studio no sabía (en tiempo de compilación) a qué método se llamará.

Creo que no hay manera de omitir la escritura de la lógica 'switch (typeof (TDetails))', donde el validador debe seleccionarse mediante TDetails. Entonces debes escribir algún tipo de fábrica, como escribió Sam Holder arriba.

PD: Perdón por mi inglés. Estoy usando stackoverflow también para estudiar inglés. :)

Cuestiones relacionadas