Is this a good or bad way to use constructor chaining? (... to allow for testing)
My motivation for chaining my class constructors here is so that I have a default constructor for mainstream use by my application and a second that allows me to inject a mock and a stub.
It just seems a bit ugly 'new'-ing things in the ":this(...)" call and counter-intuitive calling a parametrized constructor from a default constructor , I wondered what other people would do here?
(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;开发者_如何学Python
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...
}
Including a default constructor is a code smell as now the class is coupled to the concrete implementation of the IDirectoryInfoWrap. To make your life easier, use an IOC container external to the class to inject different dependencies depending on whether you are running test code or the mainstream application.
That's pretty much how I do it.
class MyUnitTestableClass
{
public MyUnitTestableClass(IMockable foo)
{
// do stuff
}
public MyUnitTestableClass()
: this(new DefaultImplementation())
{
}
}
精彩评论