Inverse of Control
Developers are expected to know basics of Object Orient Programming, notably SOLID principles. Here ‘D’ simply stands for principle of Dependency Inversion.
High level modules should not depend upon low level modules. Both should depend upon abstractions.
As the statement suggest dependencies should be architectural flow from high level models to low level models. But in some of the application the flow will be typically be that high level module is dependant on what low level module behavior/code.
This is highly discouraged and the dependencies are to be swapped. Hence this dependence inverting is achieved through Inverse of Control. Now adays Inverse of Control is used in large enterprise application while avoiding tight coupling.
Inverse of Control
Simply Inverse of Control is such method to handle decoupling described. Here consider following example:
In this example
apiController simply creates the instance of
MySQLConnection and use it to access the database. Simply
apiController depends on concrete implementation of
MySQLConncetion. Contrary to Dependency Inversion, here high level module is dependent on low level module and is coupled with concrete implementation.
MySQLConnection implementation is altered? Wouldn’t
apiController be affected as well? Huge mess is created such that with this tight coupling.
MySQLConnection is singleton implementation.
apiController would be handling only available instance. Here if another
apiController2 want to use
MySQLConnection, it would just have to wait for
apiController. There is no session management and single point failure at instance creation. (This is actually the reason that singleton is often considered as an anti-pattern)
Here comes the savior: Inverse of Control
In the code,
apiController simply depends on the abstraction not the implementation. It would rely on
IDatabaseConnection abstraction rather than concrete implementation of
IDatabaseConnection is equipped with all necessary method signatures all implementations such satisfy, either
MongoDBConnection is passed instead of
MySQLConnection, there wouldn’t be much change in
apiController since it’s dependent on any kind of
Another important thing to notice here is that
apiController doesn’t actually know the type of concrete implementation but rather received through the constructor. In IoC this is known as: Hollywood Principle as in:
Don’t call us, we’ll call you
As conveying buy this quote
apiController would just wait for an implementation of
IDatabaseConnection to be inherited through constructor rather than checking or creating instance. This is simply Inverse of Control where control is not with
apiController anymore, but its rather waiting. Waiting for implementation is even through constructors or set. Managing and injecting of concrete implementation of needed abstractions are simply done by IoC containers.
IoC containers will be responsible for managing initiating concrete implementations, injecting/setting to needed abstraction type & managing sessions.
There are multiple ways to achieve Inverse of Control, but primarily Dependency Injection and Service Locator. We will be focusing more on DI here.
Dependency Injection (DI) is a way of achieving Inverse of Control (IoC). As shown in above code
apiController is expecting
IDatabaseConnection typed instance to be passed through the constructor. This dependency of is fulfilled by injecting instance of type
IDatabaseConnection. This injecting part is handled by 3rd party and isn’t handled in
MySQLConnection nor in
This DI implementation was evident in AngularJS 1.x since this had in built DI implemented.
CalcService is registered as follows. This is injected to needed dependencies with in built DI.
myController have a dependency on
CalcService and it’s being given through constructor. It’s called as constructor injection.
Another way of DI is through set method rather than through constructor. It is called property injection. The class is initiated without the dependency and dependency is passed through
set property lately.
Service Locator pattern is also considered as possible solution for achieving IoC. Here central class known as ‘service locator’ will be used and all the controllers will typically be dependent of this central class, which is somewhat tight coupling.
Moreover this is considered as an anti-pattern by many experts and will not be discussed in this article.
IoC container and DI
IoC containers are the easiest way to implement DI & manage dependencies. The IoC container will create objects for dependency, manage complete life cycle of these created objects from creation to destruction.
Considering .NET eco-system there are notable IoC containers such as Autofac, Ninject. However considering ASP.NET Core or .NET Core, it’s equipped with in-built IoC container to manage dependencies with DI.
By simply registering dependency in
Startup.cs in ASP.NET Core MVC with in-built IoC container, dependencies will be managed accordingly. (Look into my article ‘Introduction to .NET Core’ for the basics)
Whenever there is a dependency on
IDatabaseConnection, IoC container will provide with
MySQLConnection. Any controller such as
apiController in above examples will just be injected with concrete implementation regardless of number of controllers.
Moreover what if we want to switch from MySQL to MongoDB. It’s just simple as replacing previous with above commented out line. What’s cool here is that you wouldn’t have to change any controller code since they are dependent only on abstraction. The controller code would notice any change in data storage if all goes well.
When registering abstraction (Ex:
IDatabaseConnection) with concrete implementation (Ex:
MySQLConnection) there can be different ways according to behavior. Few examples as in .NET Core IoC container are
.AddInstance and some more.
Simply if some concrete implementation is required to act as singleton just register as
.AddSingleton. This would avoid creating singleton concrete implementation which is considered as an anti pattern. Here IoC container will be responsible in managing singleton instance and its session. So this would rule out the possibility of some controller holding on to the singleton instance and starving all other controllers due to code mistake or failure. IoC container will manage singleton instead without handing control to each controllers.
Inverse of Control with Dependency Injection provides efficient way to manage dependencies in large enterprise applications. Here as shown in the examples it is clearly seen that dependencies are easily inverted and manageable this way.
So I believe you got idea about IoC and DI through this article, and comment for any clarification.