I am reading Mark Seemann's Dependency injection book and I came across bastard injection anti-pattern which I don't fully understand. I would like to get some guidance how to take apart foreign defaults from local. If the only requirement is that foreign default comes from other assembly?
What if I have design like this (it's suppose to be a library class, so I am not allowed to use IoC container):
namespace DocumentReader
{
public class DocumentReader : ISmartDocumentReader
{
private readonly ISet<IDocumentReader> documentReaders;
public DocumentReader(ISet<IDocumentReader> documentReaders)
{
this.documentReaders = documentReaders;
}
public DocumentReader()
: this(new HashSet<IDocumentReader>(new IDocumentReader[] { new TxtReader(), new PdfReader(), new DocReader() }))
{
}
public string Read(Stream stream, string fileType)
{
var reader = documentReaders.SingleOrDefault(r => r.SupportedFileType == fileType);
if(reader == null)
throw new ArgumentException("Not supported file type");
return reader.Read(stream, fileType);
}
}
}
after reading patterns chapter in the book I am in doubt if this is correct design, the goal is that this class will be the library's public API. All specific document readers (pdf, txt, doc) are all within the same assembly, but they are wrappers over some external tools or libraries like pdf box for pdfReader.
I found this question interesting Is there an alternative to bastard injection? (AKA poor man's injection via default constructor), but it doesn't dispel all my doubts. What if someday someone would add new file reader. If the default constructor is used then it won't be possible to let document reader know about the new specific reader. Should I delete the default constructor and force library users to wire (pick interesting ones) dependencies at application's composition root using IoC container?