GraphQL with ASP.NET Core (Part- III : Dependency Injection)

The letter 'D' in SOLID stands for Dependency inversion principle. The principle states,

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should depend on abstractions. - Wikipedia

Newing up instances causes strict coupling between separate code modules. To keep them decoupled from each other, we follow the 'Dependency Inversion Principle'. In this way the modules are not dependent on each other's concrete implementation rather they are dependent upon abstractions e.g. interfaces.

An abstraction can have many many implementations. So, whenever we encounter an abstraction, there should be some way of passing a specific implementation to that. A class is held responsible for this kind of servings and it should be configured in such way so. We call it a dependency injection container.

ASP.Net Core has its built-in dependency injection container. It's simple and can serve our purpose very well. Not only it can be configured to serve implementations to abstractions but also can control the lifetime of the created instances.

Currently, with our simple Hello World application, we are not bothered with instance lifetime. As of now, we will go for Singleton instance lifetime for everything,

Instead of using the concrete DocumentWriter and DocumentExecutor, we can use their abstractions i.e. IDocumentWriter and DocumentExecutor. And for this purpose, we have to configure the built-in dependency container as follows,

For the HelloWordQuery, we don't have any abstraction. We will just use the raw implementation,

services.AddSingleton<HelloWordQuery>();

The schema contains the query and later in the series it will also have mutation and other fields. We better make a separate class for it. The class will extend the Schema type and we can make its constructor injectable for the concrete HelloWorldQuery,

Notice, how we replace all the concrete type initialisations with abstractions and make our code loose coupled. Every dependency injectable service in injected via the constructor (constructor injection) at this moment.

Last but not least, we must attach the middleware in the application startup pipeline. IApplicationBuilder has an extension method called UseMiddleware which is used to attach middleware classes. So, the final look of the Configure method is as follows,