Search code examples
.netdesign-patternsdependency-injectionanti-patterns

DI Control-Freak anti-pattern: Having trouble understanding


I'm reading Dependency Injection in .NET by Mark Seemann and I can not for the life of me get my head wrapped around this:

Although the new keyword is a code smell when it comes to VOLATILE DEPENDENCIES, you don't need to worry about using it for STABLE DEPENDENCIES. The new keyword isn't suddenly "illegal" in general, but you should refrain from using it to get instances of VOLATILE DEPENDENCIES.

Maybe it's because I still can't get my head wrapped around ambient context being an injection instead of just a global variable, but I am just not getting what the author is saying.

I'd really like to understand DI top to bottom but right now I'm stuck and this is just a 1/3 the way through the book... The Control-Freak anti-pattern seems to be every single programmer that ever lived...

Anyone have any insights?


Solution

  • Volatility (to me) is a measure of the likeliness that a class will need to be changed.

    Ideally you design classes to be open to extension but closed to modification (Open Closed Principle). This isn't always possible. Those classes that you close to change are less volatile than the others.

    NDepend (a .Net static analysis metrics tool) has a metric called Instability that in my mind is synonymous. They define this as:

    Instability (I): The ratio of efferent coupling (Ce) to total coupling. I = Ce / (Ce + Ca). This metric is an indicator of the assembly's resilience to change. The range for this metric is 0 to 1, with I=0 indicating a completely stable assembly and I=1 indicating a completely instable assembly.

    You don't want Stable classes relying on less Stable ones.

    As far as deciding to inject or not, that sounds more like a class role issue. From Domain Driven Design, (DDD) Classes are usually either Entities (they have identity), Services (they orchestrate things) or Values (they are immutable and comparable, like RED or 100ml).

    You would inject Services, you would call new on Values. Entities usually come from a repository (that you inject), but internally the Repository would call new on them. Does that help?