I'm writing a brand new system and trying to stay true to the SOLID principles, specifically Interfacing and Dependency Injection. We are sticking closely to the Microsoft stack so we are using C# and the Unity container. I am in a relatively immature shop as far as SOLID concepts go so I try to keep things as simple as possible for everyone, including myself.
I have a style in which I prefer to use the constructor to accept runtime parameters and validate all the fields the object might need up front. This makes simple constructor-based injection difficult and led me down the abstract factory path.
I also have a dependency in which I need a list of Interfaces. Again this was not something that Unity elegantly supported and again the abstract factory seemed right.
http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/ http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/
I started out with lofty ideas of a generic abstract factory but to be honest I was having a difficult time figuring out how to get the container registrations right. If it was hard for me it was going to be that much harder to explain it and sell it to my team.
So I stepped back and came up with this pattern where I have an Interface and corresponding Factory Interface for each of my dependencies. The container registration becomes super simple.
_container.RegisterType<IChartFactory, ChartFactory>();
_container.RegisterType<IDocumentFactory, DocumentFactory>();
_container.RegisterType<IReportFactory, ReportFactory>();
_reportFactory = _container.Resolve<IReportFactory>();
_report = _reportFactory.CreateReport1(runTimeData);
If we ever need to change out a dependency we implement the underlying interface with the minimal added step of implementing the corresponding factory as well.
public class DocumentFactory : IDocumentFactory
{
public IDocument Create(string filePath)
{
return new Document(filePath);
}
}
public interface IReportFactory
{
IReport CreateReport1(object runTimeData);
IReport CreateReport2(object runTimeData);
}
public class ReportFactory : IReportFactory
{
IDocumentFactory _documentFactory;
IChartFactory _chartFactory;
public ReportFactory(IDocumentFactory documentFactory, IChartFactory chartFactory)
{
_documentFactory = documentFactory;
_chartFactory = chartFactory;
}
public IReport CreateReport1(object runTimeData)
{
return new ConcreteReport1(runTimeData, _documentFactory, _chartFactory);
}
public IReport CreateReport2(object runTimeData)
{
return new ConcreteReport2(runTimeData, _documentFactory, _chartFactory);
}
}
I do find it simple to understand and explain. If the dependency changes, implementing a few lines of code for the factory seems like a small price to pay as opposed to modifying every spot in the system where the type gets newed up.
More dependencies are creeping in and all these interfaces and factories are feeling like overkill. I'm worried about pushback. I'm not sure the merits are justifying the pattern and I'm not sure if I'm doing it right. Any thoughts are greatly appreciated!