When to use Dependency Inversion Principle in application?

A medium or large size application can easily get complex with tight coupling in between different layers of the application. In this post, I’ll tell you when to use Dependency Inversion Principle in application in order to decouple the layers. Let’s see what Uncle Bob has to say on this.

In a web application context, Controller is a high-level module and UnitOfWork is a low-level module. In the code above, Controller is tightly coupled with UnitOfWork that violates the dependency inversion principle. That means in cases whenever we change UnitOfWork, the Controller may need some changes as well or at-least it will need to be recompiled and assembly will need to be redeployed. This is a blocker for independently deploying assemblies.

With the help of this principle, Controller can depend on an abstraction of UnitOfWork i.e. an interface IUnitOfWork that will be implemented by UnitOfWork. So, as long as the contract remains same, controller doesn’t need care about any implementation changes in concrete UnitOfWork class. For example, the persistence layer can easily change from one version of Entity Framework to another or to another ORM, say NHibernate and the controller doesn’t need to know about this change. Plus, it doesn’t need recompilation.

Part 2

The UnitOfWork class and IUnitOfWork interface used in the code above looks like following:

UnitOfWork class definition before applying Part 2 concept

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

publicclassUnitOfWork

{

privatereadonlyApplicationDbContext _context;

publicEventRepositoryEvents{get;privateset;}

publicUnitOfWork(ApplicationDbContext context)

{

_context=context;

Events=newEventRepository(context);

}

publicvoidComplete()

{

_context.SaveChanges();

}

}

Definition of IUnitOfWork interface (before applying Part 2 concept)

C#

1

2

3

4

5

publicinterfaceIUnitOfWork

{

EventRepositoryEvents{get;}

voidComplete();

}

This interface directly depends on EventRepository which internally depends on a DbContext class and Entity Framework. So, this abstraction i.e. IUnitOfWork is dependent on details i.e. EventRepository as it is a concrete implementation. So, IUnitOfWork is not a good abstraction as even though controller is dependent on an abstraction, it is still tightly coupled with a repository and entity framework. So, to fulfil part 2 of dependency inversion principle, we can replace the usage of EventRepository with IEventRepository that knows nothing about entity framework as shown below. So now abstraction doesn’t depend on detail.

Definition of IUnitOfWork interface (after applying Part 2 concept)

C#

1

2

3

4

5

publicinterfaceIUnitOfWork

{

IEventRepositoryEvents{get;}

voidComplete();

}

Just to show, the definition of IEventRepository looks like following:

Definition of IEventRepository interface

C#

1

2

3

4

5

publicinterfaceIEventRepository

{

EventGetEvent(inteventId);

IEnumerable<Event>GetUpcomingEventsByArtist(stringartistId);

}

The code looks quite good now as it is using interfaces for abstraction and we are now following dependency inversion principle.

But wait, you may think that controller is still tightly coupled with entity framework as in the code above, it is controller’s responsibility to provide an instance of ApplicationDbContext class to UnitOfWork class instance. To completely remove this tight coupling, we need Dependency Injection (DI) concept in application.

I’ll write a blog post soon about this. So make sure you are subscribed for updates! This sums up my post to explain when to use Dependency Inversion Principle in application.

Related

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.