2010-03-23 1 views
6

Мотивация для цепочки конструкторов классов здесь заключается в том, что у меня есть стандартный конструктор для основного использования моим приложением, а второй, который позволяет мне вводить макет и заглушку.Является ли это хорошим или плохим способом использования цепочки конструкторов? (... для тестирования)

Это просто кажется уродливым «новым» в «: this (...)» вызовом и встречным интуитивным вызовом параметризованного конструктора из конструктора по умолчанию, я задавался вопросом, что здесь будут делать другие люди?

(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

Было так много дискуссий об этом на SO. Например, см. Http://stackoverflow.com/questions/300286/constructor-injection-and-default-overloads. Общий консенсус, похоже, заключается в том, что добавление конструктора по умолчанию может быть излишне запутанным, хотя некоторые утверждают, что это стоит того, когда ваша библиотека используется вызывающими программами, которые не используют инфраструктуру инъекции зависимостей. –

+0

Спасибо за ссылку. В моем случае я пишу автономное приложение, а не библиотеку. Рамки внедрения зависимостей - это еще один шаг вверх по пышной учебной лестнице, откуда я сейчас, но что-то, что я должен исследовать. – Grokodile

ответ

3

Включение конструктора по умолчанию - это запах кода, поскольку теперь класс связан с конкретной реализацией IDirectoryInfoWrap. Чтобы сделать вашу жизнь проще, используйте контейнер IOC, внешний для класса, для ввода различных зависимостей в зависимости от того, используете ли вы тестовый код или основное приложение.

+1

http://martinfowler.com/bliki/InversionOfControl.html добавлен в список чтения, спасибо. – Grokodile

0

Это довольно много, как я это делаю.

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

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