2012-02-28 23 views
11

que tienen una interfaz define como:¿Está bien pasar una secuencia a varios métodos?

public interface IClientFileImporter 
{ 
    bool CanImport(Stream stream); 
    int Import(Stream stream); 
} 

La idea es tomar cualquier secuencia de archivo y ejecutarlo a través de una serie de implementaciones de esta interfaz para determinar cuál debe manejar el archivo. Algunas de las implementaciones pueden buscar una determinada fila de encabezado, mientras que otras pueden buscar una determinada secuencia de bytes, etc. ...

Mi pregunta es, ¿está bien pasar una secuencia así siempre que nunca cierre ¿eso? Cada método debería ser responsable de restablecer el flujo a la posición 0 si es necesario, pero ¿hay algún otro problema potencial (aparte de la seguridad del hilo)? Este código realmente huele, IMO, pero no estoy seguro de una mejor manera de hacerlo.

+0

No creo que sea un mal concepto en primer lugar. No sabe qué necesitarán las implementaciones de la transmisión para que todo el flujo tenga sentido. Para garantizar que la implementación no se meta con la transmisión, podría implementar algún tipo de envoltorio alrededor de Stream (derivado de la transmisión en sí) que prohíba cualquier método que modifique la transmisión subyacente o lo que sea que necesite. Además, no necesitaría que la implementación restablezca la posición de la secuencia. La persona que llama de CanImport/Import puede hacerlo. Combinados, esto garantiza que la importación no puede dañar la transmisión subyacente. –

Respuesta

3

Para evitar que se modifique la secuencia subyacente, cree una secuencia contenedora que se deriva de Stream y reenvía solo las llamadas seguras a la secuencia envolvente. Además, no asuma que los métodos Import/CanImport restablecen la posición de la secuencia. La persona que llama de esos métodos debe restablecer el flujo a un estado válido antes de pasarlo a Import/CanImport.

+0

En este contenedor de solo lectura, ¿estaría bien anular el método Dispose para rebobinar automáticamente el flujo pero no cerrarlo? – Chris

+0

Sí, eso podría funcionar, de esa manera puede usar un cómodo bloque de uso para las llamadas a CanImport/Import –

2

Si cada función devuelve la transmisión tal como lo obtuvo, no creo que haya ningún problema.

+0

¿Por qué el método no debe modificar la secuencia? Creo que leer y escribir en la transmisión es la razón por la que lo pasarías por alto. – cadrell0

+0

Si modifica la secuencia, puede entrar en todo tipo de dependencias entre funciones. Puede estar bien, pero OP habló sobre rebobinar el flujo cada vez. – zmbq

2

Esto no debería ser un problema.

A pesar de que probablemente reestructurar ligeramente:

public interface IClientFileImporter 
{ 
    int Import(Stream stream); 
} 

Entonces tendría el método de importación devuelve un -1 si no era capaz de hacerlo. Podría hacer que tu otro código sea un poco más simple.

+0

Estoy de acuerdo con Chris, buena respuesta Chris. Creo que esto lo hará un poco más fácil –

0

Está perfectamente bien pasar la misma secuencia a varios métodos.

Tenga cuidado con las transmisiones no buscables: hay transmisiones que no puede restablecer. El comentario de Andre Loker tiene buenos consejos para incluir a Stream, de modo que los métodos de CanImport no alteren la transmisión real.

También puede considerar proporcionar explícitamente una parte del encabezado de la secuencia a los métodos de CanImport, también los hará menos flexibles.

0

Si le preocupa pasar un flujo continuo porque podría terminar ejecutando código externo que podría no ser confiable, entonces lo mejor que puede hacer es crear una nueva secuencia de solo lectura y pasarla para que ningún código externo pueda cambie el contenido del archivo hasta que esté seguro de querer dejarlo.

public class ReadonlyStream : Stream 
{ 
    public ReadonlyStream(Stream baseStream) 
    { 
     ownerStream = baseStream; 
    } 

    private Stream ownerStream; 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override int Write(byte[] bits, int offset, int count) 
    { 
     throw new InvalidOperationException(); 
    } 

    // Other code ommitted 
} 
Cuestiones relacionadas