2011-05-31 10 views
5

Estoy usando IoC y DI para mi proyecto.Interfaz de solo lectura privada: ¿es redundante?

Sin embargo, me pregunto si es una buena práctica tener la siguiente:

private readonly IMyService myservice; 

como el campo dentro de la clase que es un consumidor del servicio. El campo está establecido en el constructor.

Estoy seguro de que he visto esto en alguna parte y lo he recogido. Sin embargo, también ver:

private IMyService myservice; 

y parece ser suficiente. ¿Hay algún propósito de tener un campo de solo lectura para la interfaz de servicio inyectado? ¿Cuáles son las ventajas?

Respuesta

7

Considero que el uso de la palabra clave readonly es una parte central de la implementación adecuada de Constructor Injection.

public class MyClass 
{ 
    private readonly IMyService myservice; 

    public MyClass(IMyService myservice) 
    { 
     if (myservice == null) 
     { 
      throw new ArgumentNullException("myservice"); 
     } 
     this.myservice = myservice; 
    } 
} 

Ni la palabra clave readonly ni la Cláusula de Guardia son técnicamente necesaria para implementar Constructor de inyección. Sin embargo, ambos ayudan a fortalecer las invariantes de la clase. This is what encapsulation is all about.

4

Un campo readonly significa que solo se puede escribir en el ctor. Una vez que se completa, la referencia no se puede cambiar ni destruir. Es muy útil para inicializar el estado y reforzar la inmutabilidad.

9

El hecho de que sea una interfaz es irrelevante. Aplicar el modificador readonly en un campo evita que usted (u otra persona) cambie su valor una vez que se haya construido el objeto. Solo se puede asignar en el constructor.

+0

¿Es una buena práctica usarlo con interfaces o es superfluo? – jaffa

+2

¡No tiene nada que ver con interfaces! –

2

La ventaja de tener readonly en el campo es su clara declaración de que el campo no cambiará durante la vida de la instancia que lo contiene. En muchos escenarios, esto hace que sea más fácil razonar sobre el comportamiento de un método dado. Por ejemplo

void Method() { 
    var marker = myservice.StartOperation(); 
    try { 
    SomeOtherMethod(); 
    } finally { 
    myservice.StopOperation(marker); 
    } 
} 

Suponga que StartOperation y StopOperation son métodos que debe ser llamado por parejas en un dado IMyService ejemplo. Cuando myservice es un campo readonly, puede observar solo esta función y tener un alto grado de confianza para cumplir este contrato.

Sin embargo, si no es readonly debe ser inmediatamente sospechoso de SomeOtherMethod y cualquier otro método llamado transitivamente desde esa función. Si alguno de ellos pudiera restablecer el campo myservice de repente, estarías en violación del contrato y terminarías con algunos errores muy sutiles.

1

Here is the documentation for the readonly keyword.

Cuando se aplica a un campo de una clase, readonly indica al lector "este campo no va a cambiar durante la vida útil de esta instancia." Esa es información muy útil para las dependencias, que no están destinadas a cambiar después de recibirlas en el constructor.

Un intento equivocado de alterar una dependencia da como resultado un error en tiempo de compilación, recordándole a usted o a cualquier otra persona que esté modificando la clase que las dependencias inyectadas no deberían cambiar.Esta es una situación mucho más fácil de detectar y corregir que omitir la palabra clave readonly y luego tener que rastrear un error debido a una reasignación.

En resumen, sí, es una buena práctica declarar algo readonly si no lo cambia después de que se construye el objeto, ya que evitará que todos los autores futuros cometan ese error.

Cuestiones relacionadas