Consider a logging system – used absolutely everywhere in your codebase.
(note – logging is just an example, don’t take it too literally and point me at your favourite logging system).
public interface ILogger
{
void LogMessage(string message);
}
// Just used for testing, do nothing
public class NullLogger : ILogger
{
public void LogMessage(string message) { }
}
public class FileLogger : ILogger
{
public FileLogger(string fileName){...}
public void LogMessage(string message) {
// Log to a file here
}
}
No I could make every single class have ILogger in ctor or param and use some IoC framework.
Or I could just use something like
public static class Globals
{
public static ILogger Log = new NullLogger();
}
Use at any point by Globals.Log.LogMessage("Hello Logging World");
And at ‘Compositon Root’ (main entry point of program) set Globals.Log = new FileLogger("somefile.log");
Or this could be done as a Singleton of course.
When is using DI and optionally IoC a step too far? What would you do in this case?
3
Does your app need to work? Yes? Then use DI.
Having statics makes your code troublesome to test automatically (since tests often should be run in parallel to decrease turnover time and to help verify concurrency of your code). If you can’t automatically test your code, it will be more difficult to make it work properly.
Now, an IoC container is probably overkill. Personally, I’ve seen them cause more trouble (integration troubles, overhead of configuration) than they solved. But having at least optional DI (that maybe defaults to a static instance even) will help you avoid many problems.
If you have a quicky throw away app that doesn’t really need to work completely, then sure; hack away. Otherwise, take the time to do it right.
4
> using DI and optionally a IoC framework [is] a step too far
if you
- don’t want to do automated (unit-)testing and if you
- don’t have separate components of the app (i.e. dlls) that should be changed (or recompiled) independently of the main app.
1