I am facing a problem with dependency inversion in a factory method and it is also breaking Open Closed principle. My code looks like below codes
public interface IWriter
{
void WriteToStorage(string data);
}
public class FileWriter : IWriter
{
public void WriteToStorage(string data)
{
//write to file
}
}
public class DBWriter : IWriter
{
public void WriteToStorage(string data)
{
//write to DB
}
}
Now I an using a factory class to solve the object creation. It look like below code
public interface IFactory
{
IWriter GetType(string outputType);
}
public class Factory : IFactory
{
public IWriter GetType(string outputType)
{
IWriter writer = null;
if (outputType.Equels("db"))
{
writer = new FileWriter();
}
else if (outputType.Equels("db"))
{
writer = new DBWriter();
}
}
}
Now the problem is the Factory class is breaking Open closed principle so it also breakes Dependency Inversion Principle
And then
public interface ISaveDataFlow
{
void SaveData(string data, string outputType);
}
public class SaveDataFlow : ISaveDataFlow
{
private IFactory _writerFactory = null;
public SaveDataFlow(IFactory writerFactory)
{
_writerFactory = writerFactory;
}
public void SaveData(string data, string outputType)
{
IWriter writer = _writerFactory.GetType(outputType);
writer.WriteToStorage(data);
}
}
As the above factory class is breaking the dependency inversion I remove the Factory class and change the SaveDataFlow class like below
public class SaveDataFlow : ISaveDataFlow
{
private IWriter _dbWriter = null;
private IWriter _fileWriter = null;
public SaveDataFlow([Dependency("DB")]IWriter dbWriter,
[Dependency("FILE")]IWriter fileWriter)
{
_dbWriter = dbWriter;
_fileWriter = fileWriter;
}
public void SaveData(string data, string outputType)
{
if (outputType.Equals("DB"))
{
_dbWriter.WriteToStorage(data);
}
else if (outputType.Equals("FILE"))
{
_fileWriter.WriteToStorage(data);
}
}
}
And resolved those dependencies using Unity Framework
container.RegisterType<IWriter, DBWriter>("DB");
container.RegisterType<IWriter, FileWriter>("FILE");
Yet eventually I am ending up breaking Open Closed Principle. I need a better design/solution to solve such a problem yet I must follow SOLID Principles.
[Dependency("DB")]you are coupling yourself to you DI framework which isn't ideal either. - Callum LiningtonSaveDataFlowneeds to work off string input types? Can't you simply inject the proper writer? As for the factory, if you wish to make it extensible then you could use reflection to scan assemblies and find all implementors ofIWriterin order to register them auto-magically. - plalx