How to Say Hello to SRP&DI&IoC ?

Beyza Celep
7 min readAug 8, 2022
https://www.dreamstime.com/illustration/software-engineer-cartoon.html

Hello,

For approximately 2 years, I have a reading list contains all my important & favorite articles that I want to return back from time to time to renew my knowledge. This post is going to be about one of them : “How to say Hello to ASP.NET Core ?” by Burak Selim Şenyurt. Before getting started I let you know that the link of his article is left below.

He asked some questions at the end of the article and wanted us to document the answers, so here we go with the first question :

1-) How would you explain Single Responsibility and Dependency Inversion Principle to someone who doesn’t know ?

  • This question is about 2 important concepts that I guess we all know very well theoretically : S and D of SOLID principles. But when it’s come to explain to someone doesn’t know, it requires us to internalizing the theory, I believe. So let’s warm up and get it started.

Single Responsibility principle, as the name indicates, means a class should have one and only one job to do therefore one and only reason to change. A basic but effective real world example : if you read my previous posts, you probably know that I love to give examples about my passions when getting deep in the subjects :) Now let’s think about professional soccer players. They all have their own positions where they are best and experts. If you put a forward player in middle attacker position, you can not get the results you expect. Attention that I don’t say it’s impossible, but not effective. And also that kind of casting, makes them changeable by many reasons, not the only for the injuries or game quality etc. This is actually what SRP is. In OOP, a class should only do one job which comes with the consequence that a class should have one and only reason to change. (Class / software module).

Dependency Inversion, the D of the SOLID, says a hight level class must not depend upon a lower class ; they must both depend upon abstractions. Secondly, abstractions must not depend on details ; details must depend upon abstractions. To explain, I am going to implement a piece of code. But before all, I want to answer another question from the main post here to get things clearly.

2-) What does High-Level Component and Low-Level Component mean? Can you research and describe them in one sentence ?

  • In my point of view, answering this question gonna help us to get Dependency Inversion principle quickly & clearly.

Low level components are basically the sub systems that help the high level component to do the work. High level modules contain the important concepts, decisions and business rules of an application.

This definition of high-level modules is totally enough to understand :

The identity of application .

Low levels modules contain detailed informations, jobs to achieve what higher level modules demand.

Low level classes are the simple workers that perform actions, while high level classes are the management class that orchestrate the low level classes.

Since we are ok about what high-level & low level component mean, let’s continue with first question, a piece of code example about Dependency Inversion principle.

We need :

-A high level class

-A low level class

-Abstraction layer between them to achieve the dependency inversion goal.

Imagine a basic scenario that we have a DbOperation class where we do save, delete etc.

This DbOperation class has a Save() method.

In Save(), we want logging operations that comes from :

XmlLogger class. -> This is the low level class.

XmlLogger has Log() that does the logging operation the way we need.

Now let’s see the first implementation of this basic scenario :

The scenario is simple. We have out initial struct now. But pay attention:

DbOperation is thew high level class but depend upon the low level class(es) (XmlLogger and future versions). If I change the low level class, the high level module is going to be effected. Or, if I add any other type of logger class, I still need to change the higher class.

Now, we need to fix this tightly coupled code according to Dependency Inversion principle.

We need an abstraction between, as I said previously. So, firstly I create the interface that contains the low level classes :

As you can see the high-level class is depend upon the abstraction not the low level classes. And we can easily add different type of loggers, still the high level class doesn’t have to change.

3- ) Are Inversion of Control and Dependency Inversion Principle the same ? How would you describe the differences ?

  • Of course, not.But first let me talk about Inversion of Control (IoC).

The main goal of IoC is to minimize dependencies. Instead putting all responsibility of creating, managing etc. of the dependencies to developer’s shoulders, it aims to leave these responsibilities to the framework. IoC, dependency injection these are the techniques that applies Dependency Inversion Principle.

“Inversion of Control is a design principle used by framework libraries that allow the framework to regain some control from the application.” — Martin Fowler

He also uses the term of Hollywood Principle : “Don’t call us, we will call you.”.

Also, please note that decoupling is an important part of IoC.

4-) What do you think are the advantages of using DI Container?

“A DI Container is a framework to create dependencies and inject them automatically when required.”

https://www.dotnettricks.com/learn/dependencyinjection/what-is-ioc-container-or-di-container#:~:text=It%20automatically%20creates%20objects%20based,a%20simple%20and%20easy%20way.

“The magic of DI container is to avoid doing a very tiresome manual binding of all your objects. Binding that will need to be updating every time a single thing change. Whatever is made of your DI container (service locator pattern inside) is not your problem. What matter to you is that it works and you need to explicitly reference the service locator or whatever he’s using inside most of the time (except special cases as always). ”

So, basically the DI containers help us to manage dependencies. We don’t have to worry about object creation, creation of required dependencies, triggering at the right time or disposing at the right time. These whole processes are managed by DI containers instead of us doing manually.

Injection of dependencies manually is a tiring process. The bigger the application gets, the more your dependencies get and each of this dependencies will have more than one dependencies.

That means one change -> adjust all again. DI containers say just register the service and let me complete all the process for you.

But it’s critical to remember, what your application needs or how big&complex is your project kinda questions are the most important. For simple projects, using DI container seems like an overwork.

Thank you for reading. If you have any questions or recommendations please feel free to comment & contact. Don’t forget to see the links below !

See you in next post ! :)

References & Recommendations:

https://www.gencayyildiz.com/blog/tek-sorumluluk-prensibisingle-responsibility-principle-srp/

--

--