Dependency Injection as a means of inversion of control has permeated at least the opinions of most software developers (although there may be a company full of old, stubborn developers somewhere…). However, how much Dependency Injection does one really need?
When I wrote the Scala-version of GoodNight using Akka Play, I found it to support an implementation style that does not require a DI framework; it even did not require any dependency injection. They call this “Compile Time Dependency Injection“, which is a very fancy term for the fact that you have an entrypoint function where you manually create your objects and stitch them together:
class GoodnightComponents(context: Context) { lazy val database = slickApi.[...] lazy val silhouette = new SilhouetteProvider([...]) lazy val authSignUp = new SignUp(database, silhouette, [...])
Interestingly, this is in fact still the concept of Dependency Injection: The invidiual classes are still loosely coupled, and do not create each other, but request each other (or their interfaces) in their constructors.
Turns out, this is also what Mark Seemann suggests how you should write a library (in this case for C#), in order to have it be easily composable with any kind of DI framework.
Now, on to inject (heh) this into the Asp.Net Core DI container. What fun.
Results: Mark wrote a separate post about how to write DI friendly frameworks. He suggests an extremely simple approach: For each interface that a framework user can implement, provide a factory interface. The user does know how to create the concrete types and through the factory interface, the framework can easily request that creation.