2010-03-23 5 views
6

Mi motivación para encadenar los constructores de mi clase aquí es que tengo un constructor por defecto para el uso general de mi aplicación y un segundo que me permite inyectar un simulacro y un talón.¿Es esta una buena o mala manera de usar el encadenamiento de constructores? (... para permitir la prueba)

Parece un poco feo 'nuevo' -ing cosas en el ": esto (...)" llamada y contra-intuitivo llamando a un constructor parametrizado desde un constructor predeterminado, me pregunté qué harían otras personas aquí?

(FYI ->SystemWrapper)

using SystemWrapper; 

public class MyDirectoryWorker{ 

    // SystemWrapper interface allows for stub of sealed .Net class. 
    private IDirectoryInfoWrap dirInf; 

    private FileSystemWatcher watcher; 

    public MyDirectoryWorker() 
     : this(
     new DirectoryInfoWrap(new DirectoryInfo(MyDirPath)), 
     new FileSystemWatcher()) { } 


    public MyDirectoryWorker(IDirectoryInfoWrap dirInf, FileSystemWatcher watcher) 
    { 
     this.dirInf = dirInf; 
     if(!dirInf.Exists){ 
      dirInf.Create(); 
     } 

     this.watcher = watcher; 

     watcher.Path = dirInf.FullName; 

     watcher.NotifyFilter = NotifyFilters.FileName; 
     watcher.Created += new FileSystemEventHandler(watcher_Created); 
     watcher.Deleted += new FileSystemEventHandler(watcher_Deleted); 
     watcher.Renamed += new RenamedEventHandler(watcher_Renamed); 
     watcher.EnableRaisingEvents = true; 
    } 

    public static string MyDirPath{get{return Settings.Default.MyDefaultDirPath;}} 

    // etc... 
} 
+1

Ha habido una buena cantidad de discusión sobre esto en SO. Por ejemplo, vea http://stackoverflow.com/questions/300286/constructor-injection-and-default-overloads. El consenso general parece ser que agregar el constructor predeterminado puede ser innecesariamente confuso, aunque algunos argumentan que vale la pena cuando las personas que llaman usan su biblioteca y no usan un marco de inyección de dependencia. –

+0

Gracias por el enlace. En mi caso, estoy escribiendo una aplicación independiente en lugar de una biblioteca. Los marcos de inyección de dependencia son otro escalón de la curvilínea escala de aprendizaje de donde estoy ahora pero algo que debería investigar. – Grokodile

Respuesta

3

La inclusión de un constructor por defecto es un olor código como ahora la clase se acopla a la aplicación concreta de la IDirectoryInfoWrap. Para hacerte la vida más fácil, utiliza un contenedor IOC externo a la clase para inyectar dependencias diferentes dependiendo de si estás ejecutando el código de prueba o la aplicación convencional.

+1

http://martinfowler.com/bliki/InversionOfControl.html agregado a mi lista de lectura, gracias. – Grokodile

0

Eso es más o menos como lo hago.

class MyUnitTestableClass 
{ 
    public MyUnitTestableClass(IMockable foo) 
    { 
     // do stuff 
    } 

    public MyUnitTestableClass() 
     : this(new DefaultImplementation()) 
    { 
    } 
} 
Cuestiones relacionadas