Download as pdf or txt
Download as pdf or txt
You are on page 1of 97

Dependency Injection in ASP.

NET Core

Posted by Vladimir Pecanac | Updated Date Dec 29, 2021 | 4

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

In this article, we’re going to talk about dependency injection, one of the most frequently used design patterns out there.
There are many tutorials about dependency injection, but in this one, we’re going to focus on understanding why the
dependency injection is used and how to use it properly in ASP.NET Core.

The source code for this article can be found on the Dependency Injection in ASP.NET Core Applications repo on GitHub.

So, let’s start.

What is Dependency Injection?

Dependency Injection (often called just DI) is a software design pattern that helps us create loosely coupled
applications. It is an implementation of the Inversion of Control (IoC) principle, and Dependency Inversion Principle (D
in SOLID).

The Inversion of Control principle is a design pattern in which the control flow of the application is reversed. We can use it
to our benefit to decouple the parts of our application. This might sound a bit odd, but we’ll see how it works in a moment.
Dependency Injection is just one way of implementing the Inversion of Control principle. Inversion of Control can be
achieved via other means like delegates, events, or other design patterns like factory method for example.
The Inversion of Control also states that objects should not create other objects they depend on. These should be injected via
external service or container.

You can read more about the Dependency Inversion Principle in our SOLID principles series.

Normal Flow vs Dependency Inversion

In a more graphical way, here’s how the typical workflow looks like:
In a lot of applications, the compile-time dependencies flow in the same direction as the runtime execution. This is wrong
because dependencies should be oriented towards the abstraction and not implementation. Class A is referencing a
method from Class B, and Class B is referencing the method from Class C. This creates a direct dependency graph that
should be avoided at all costs.

This can be corrected by using interfaces, or rather coding to interfaces:


This time around, Class A calls a method from an abstraction – Interface B that Class B implements. Similarly, Class B
calls a method from an Interface C instead of Class C directly. Thus, Class B is no longer a dependency of Class A, and
Class A and Class B remain loosely coupled. Class B depends on the interface controlled by Class A and therefore the
compile-time dependencies are inverted. At the same time, runtime flow remains the same.
Inversion of Control with the Constructor Injection

Constructor injection is by far the most used type of Dependency Injection. Dependency injection is built in ASP.NET
Core, and we’re encouraged by the framework to use it. Actually, we might even find it hard not since it’s deeply integrated
into the framework.

But let’s put all this theory to practice. We are going to create an example of a control flow without a DI first to see how it
looks like.

We’ll create a simple PlayerGenerator for a potential game. Let’s create a simple model first. We can create a Player class
and some enums to determine the gender and the hair color of that player:

public class Player


{
public string Name { get; set; }
public Gender Gender { get; set; }
public int Age { get; set; }
public HairColor HairColor { get; set; }
public int Strength { get; set; }
public string Race { get; set; }
}
public enum Gender
{
Male = 0,
Female = 1
}
public enum HairColor
{
Blue = 0,
Black = 1,
Brown = 2,
Green = 3,
Pink = 4,
White = 5,
Orange = 6
}

Now, we need to create a PlayerGenerator service in the Services folder:

public class PlayerGenerator


{
private readonly string[] _maleNames = { "Jon Irenicus", "Kagain", "Minsc", "Xzar", "Drizzt Do'Urden", "Sarevok",
"Elminster" };
private readonly string[] _femaleNames = { "Imoen", "Jaheira", "Dynaheir", "Branwen", "Bodhi", "Shar-Teel", "Safana" };
public Player CreateNewPlayer()
{
string playerName;
var random = new Random();
var playerNameIndex = random.Next(7);
var playerGenderIndex = random.Next(2);
var playerHairColorIndex = random.Next(7);
var playerAge = random.Next(18, 100);
var strength = random.Next(8, 18);
if (playerGenderIndex == 0)
playerName = _maleNames[playerNameIndex];
else
playerName = _femaleNames[playerNameIndex];
return new Player
{
Name = playerName,
Gender = (Gender)playerGenderIndex,
HairColor = (HairColor)playerHairColorIndex,
Age = playerAge,
Strength = strength,
Race = "Human"
};
}
}

This piece of code creates a random male or female human player character and uses some randomly generated values to
determine character details. It’s a really simple generator that has only one method, and its only purpose is to create new
players.

Now we can go to our GameController (renamed HomeController) and modify the Index() method:

public IActionResult Index()


{
var playerGenerator = new PlayerGenerator();
var newPlayer = playerGenerator.CreateNewPlayer();
return View(newPlayer);
}

We’re simply creating a new instance of the PlayerGenerator and calling the CreateNewPlayer() method to
create a new player and send it to the view.

The only thing remaining is to change the Index view a bit to show our new player details:

@{
ViewData["Title"] = "Game Page";
}
<div>
<h2>New Player Info</h2>
<p>Name: @Model.Name</p>
<p>Gender: @Model.Gender</p>
<p>Race: @Model.Race</p>
<p>Age: @Model.Age</p>
<p>Hair Color: @Model.HairColor</p>
<p>Strength: @Model.Strength</p>
</div>

Now if we run the application we should get a randomly created player character:

Excellent. Drizzt Do’Urden is ready to play his turn.

The Problem(s)

Since our controller is directly creating a PlayerGenerator instance, we’ve created several huge problems.
Our controller is no longer just the controller, so we’ve violated the Single Responsibility Principle. Controllers should not
create instances of other classes.

We’ve also produced a tightly coupled source code. Say for example we want to change the PlayerGenerator class
with another one, like BetterPlayerGenerator class which creates players in a completely different way. We would
need to change our controller too:

public IActionResult Index()


{
var playerGenerator = new BetterPlayerGenerator();
var newPlayer = playerGenerator.CreateNewPlayer();
return View(newPlayer);
}

This is not ideal, and you see how this can propagate through the many different layers of applications easily.

We’ve also made the GameController harder to test. Since the PlayerGenerator is created inside the Index()
method, we can’t mock it. This would make our unit tests unreliable. We aren’t able to test the unit in this case, so the tests
wouldn’t even be the real unit tests. This would make them more like integration tests since we would be testing the
integration of PlayerGenerator and GameController.

Lastly, we’re creating dirty and unreadable code in the long run. Imagine if every dependency in the project is created this
way. We would have a lot of redundant code, and we would have to change an entire application whenever the slightest
change in logic is made.
So what can we do to improve this situation?

We can use dependency injection.

Let’s see how.

Making the Solution More Flexible with Dependency Injection

First, we need to create an interface IPlayerGenerator. We can do that manually, or we can go to PlayerGenerator
class and press Ctrl + . on the class name and click on the Extract Interface. The latter approach is faster, and it
automatically adds an inheritance to our classes:

public class PlayerGenerator : IPlayerGenerator


{
...
}

And we can manually add it to the BetterPlayerGenerator class:

public class BetterPlayerGenerator : IPlayerGenerator


{
..
}
And the interface is generated:

public interface IPlayerGenerator


{
Player CreateNewPlayer();
}

Now both our classes implement the IPlayerGenerator class.

Now we need to go to our GameController and use the Dependency Injection to add our dependency:

private readonly ILogger<GameController> _logger;


private readonly IPlayerGenerator _playerGenerator;
public GameController(ILogger<GameController> logger, IPlayerGenerator playerGenerator)
{
_logger = logger;
_playerGenerator = playerGenerator;
}
public IActionResult Index()
{
var newPlayer = _playerGenerator.CreateNewPlayer();
return View(newPlayer);
}

We’ve added our dependency via constructor injection, and we’ve assigned it to a private readonly field. This is a good
practice, as we’re preventing accidental assignment anywhere else outside the constructor.

Now we can simply call the _playerGenerator.CreateNewPlayer() method in the Index() method.

Great, but what happens now if we run the application?

We get a nice big InvalidOperationException, stating that the service cannot be activated.

But why does this happen?


It happens because we haven’t registered our service yet with our dependency injection container. It’s only logical because
the container is not aware of which interface resolves to which class, yet.

Let’s see how we can register our service.

Registering the Service with Dependency Injection Container

In order to get rid of that InvalidOperationException, we need to register our service.

We can do that in our Startup class, by adding a single line in the ConfigureServices() method:

public void ConfigureServices(IServiceCollection services)


{
services.AddScoped<IPlayerGenerator, PlayerGenerator>();
services.AddControllersWithViews();
}

We’ve added the PlayerGenerator service to the service collection with AddScoped() method.

In short, scoped lifetime means that the instance is created on every request. For now, let’s leave it like this, but we’ll talk
more about dependency injection lifetimes.

The important thing is that the service registration is necessary and that we can add it as a transient, scoped or singleton
service to our IServiceCollection.

If we run the application again, it should work just fine.


How does Dependency Injection Help?

So what happens now if we want to introduce the BetterPlayerGenerator class now in our controller?

We don’t need to change a thing in the GameController itself!

We just need to change the registration in the Startup.cs:

public void ConfigureServices(IServiceCollection services)


{
services.AddScoped<IPlayerGenerator, BetterPlayerGenerator>();
services.AddControllersWithViews();
}

That’s it!

Although the BetterPlayerGenerator has a completely different player generation logic, it doesn’t affect our
controller.
That’s a much better way of doing it!

So we’ve completed several goals with this approach:


 Made the code cleaner
 Decoupled controller from the service implementation
 Made the controller easier to test
 Created a more robust foundation for our solution (using abstractions over concrete classes)

Different Service Registration Lifetimes

As we’ve already mentioned, there are three different registration lifetimes we can choose from when registering our
services.

These are:

 Transient – We can use this for lightweight, stateless services. Each time the service is called, the new instance is
created
 Scoped – The instance of the service is created once per request and within that request (scope) it is reused
 Singleton – The instance is created only once

We’ll talk more about these DI lifetimes.

Conclusion

In this article, we’ve covered concepts like Dependency Injection, Inversion of Control, and Dependency Inversion
principle. We’ve learned how they are related and how the application control flow can be inverted by using dependency
injection.

We’ve also created a small example to see how we can apply dependency injection in ASP.NET Core application, and
we’ve seen how beneficial this approach can be.
Next time, we’ll talk more about different dependency injection lifecycles.

Dependency Injection in ASP.NET Core MVC

Posted by Code Maze | Updated Date Jan 13, 2022 | 2

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

In this article, we are going to discuss an important concept of ASP.NET Core MVC – Dependency Injection.

If you’ve missed some of the previous articles in the series we recommend visiting the series page: ASP.NET Core MVC
Series.

To download this article’s source code visit: Dependency Injection in ASP.NET Core MVC.

So, let’s get down to it.

Dependency Inversion and Dependency Injection

Dependency Inversion is one of the core software design principles which we use to create modules that are loosely
coupled. While creating applications, we can achieve this using a technique called Dependency Injection.
Dependency Injection (DI) is the method of injecting the dependent modules into our classes.
We have discussed this in detail in one of our other article Dependency Inversion Principle. We’ve also discussed the
concept of Dependency Injection and how to implement it.

So, in this section, we are going to look at the support for Dependency Injection in an ASP.NET Core MVC application.

Injecting Dependencies into Controllers

ASP.NET Core supports Dependency Injection(DI) between classes and their dependencies. MVC Controllers request
dependencies explicitly via constructors. Furthermore, ASP.NET Core has built-in support for dependency injection, hence
making the application easier to test and maintain.

We add services as a constructor parameter and the runtime resolves the service from the service container. We typically
define services using interfaces.

When we implement a repository pattern in the ASP.NET Core MVC application, we make use of Dependency Injection in
our controllers. We have explained how to implement a simple data repository in the article section Implementing a simple
data repository.

Let’s create an ASP.NET Core MVC application and implement a simple data repository as described in the article.

First of all, let’s create an interface IDataRepository:

public interface IDataRepository<TEntity>


{
IEnumerable<TEntity> GetAll();
void Add(Employee employee);
}

Then let’s create a class EmployeeManager implementing the IDataRepository interface:

public class EmployeeManager : IDataRepository<Employee>


{
public void Add(Employee employee)
{
throw new NotImplementedException();
}
IEnumerable<Employee> IDataRepository<Employee>.GetAll()
{
return new List<Employee>() {
new Employee(){ }
};
}
}

The next step is to add the service to the service container. We need to do that in the ConfigureServices() method in
the Startup.cs class:
services.AddScoped<IDataRepository<Employee>, EmployeeManager>();

By doing so, we have configured the repository using Dependency Injection.

Next, let’s create the EmployeeController with the Index() action method to get the list of all employees:

public class EmployeeController : Controller


{
private readonly IDataRepository<Employee> _dataRepository;
public EmployeeController(IDataRepository<Employee> dataRepository)
{
_dataRepository = dataRepository;
}
public IActionResult Index()
{
IEnumerable<Employee> employees = _dataRepository.GetAll();
return View(employees);
}
}
Here, we first declare a _dataRepository variable of type IDataRepository<Employee>. Later, we inject it
through the constructor.

We can also inject a service directly into an action method without using a constructor injection. We can use the
[FromServices] attribute for that:

public IActionResult Index([FromServices] IDataRepository<Employee> _dataRepository)


{
IEnumerable<Employee> employees = _dataRepository.GetAll();
return View(employees);
}

TheFromServices attribute specifies that an action parameter should be bound using the request services.

Great. We have learned how to use Dependency Injection to provide dependencies into a Controller.

Now, let’s look at how to Inject dependencies into Views.

Injecting Dependencies into Views

ASP.NET Core supports injecting dependencies into Views.

When to Inject Dependencies into Views

Injecting services into views is a deviation from the MVC concept. But in some cases, we may have view-specific services
which return the data that we use only for populating the view elements. An example is a service that gives a set of values
that we need to display in a list control. In such scenarios, we can inject services directly into views. View injection can be
useful to populate options in UI elements, such as dropdown lists.

Consider a form to create a book that includes options for specifying a genre. Rendering the data using a standard MVC
approach would require the controller to request data access services for this set of options and then populate a Model or
ViewBag with the set of options to be bound.

An alternative approach is to inject the services directly into a view. This approach minimizes the amount of code required
by the controller as we move the view element construction logic into the view itself.

How to Inject services into Views

We can inject a service into a view using the @inject directive. @inject adds a property to our view and initialize it
using DI:

@inject <type> <name>

Let’s create a controller action method to display a book creation form:

public class BooksController : Controller


{
public IActionResult Create()
{
return View();
}
}

Then let’s create a Book model class:

public class Book


{
public int Id { get; set; }
[Display(Name = "Book Title")]
public string Title { get; set; }
public string Genre { get; set; }
[DataType(DataType.Currency)]
[Range(1, 100)]
public decimal Price { get; set; }
[Display(Name = "Publish Date")]
[DataType(DataType.Date)]
public DateTime PublishDate { get; set; }
}

For the next step, let’s define a BooksLookupService for supplying the list data for Genres:
public class BooksLookupService
{
public List<string> GetGenres()
{
return new List<string>()
{
"Fiction",
"Thriller",
"Comedy",
"Autobiography"
};
}
}

Then let’s create a view and inject an instance of BooksLookupService into it:

@model WorkingWithDI.Models.Book
@inject WorkingWithDI.Models.Services.BooksLookupService BooksLookupService
@{
ViewData["Title"] = "Create";
var genres = BooksLookupService.GetGenres();
}
<h1>Create</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div>
<label asp-for="Genre" class="control-label"></label>
<select asp-items="@(new SelectList(genres))" class="form-control" ></select>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>

This will supply the list values into the view.

As the last step, we need to register the types that we request through dependency injection in
Startup.ConfigureServices(). If a type is unregistered, it throws a runtime exception.

services.AddTransient<BooksLookupService>();

That’s it. Now let’s run the application and navigate to Create Books form:
We can see that the list of Genres is populated by getting the values from the BooksLookupService.

Excellent, we have learned how to inject a dependency directly into the view.

Conclusion

In this article we have learned the following topics:

 The principle of Dependency Inversion and how to achieve it using Dependency Injection
 Injecting dependencies into Controllers
 Injecting dependencies into Views of an ASP.NET Core MVC application

In the next part of this series, we are going to learn about unit testing in ASP.NET Core MVC.

SOLID Principles in C# – Dependency Inversion Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 4

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!
The basic idea behind the Dependency Inversion Principle is that we should create the higher-level modules with its
complex logic in such a way to be reusable and unaffected by any change from the lower-level modules in our application.
To achieve this kind of behavior in our apps, we introduce abstraction which decouples higher from lower-level modules.

Having this idea in mind the Dependency Inversion Principle states that

 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.

We are going to make all of this easier to understand with an example and additional explanations.

To download the source code for this project, check out the Dependency Inversion Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

What are the High-Level and Low-Level Modules

The high-level modules describe those operations in our application that have more abstract nature and contain more
complex logic. These modules orchestrate low-level modules in our application.

The low-level modules contain more specific individual components focusing on details and smaller parts of the application.
These modules are used inside the high-level modules in our app.

What we need to understand when talking about DIP and these modules is that both, the high-level and low-level modules,
depend on abstractions. We can find different opinions about if the DIP inverts dependency between high and low-level
modules or not. Some agree with the first opinion and others prefer the second. But the common ground is that the DIP
creates a decoupled structure between high and low-level modules by introducing abstraction between them.

Dependency Injection is one way of implementing the Dependency Inversion Principle.


Example Which Violates DIP

Let’s start by creating two enumerations and one model class:

public enum Gender


{
Male,
Female
}
public enum Position
{
Administrator,
Manager,
Executive
}
public class Employee
{
public string Name { get; set; }
public Gender Gender { get; set; }
public Position Position { get; set; }
}

To continue, we are going to create one low-level class which keeps (in a simplified way) track of our employees:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
}

Furthermore, we are going to create a higher-level class to perform some kind of statistical analysis on our employees:

public class EmployeeStatistics


{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers()
{
//logic goes here
}
}

With this kind of structure in our EmployeeManager class, we can’t make use of the _employess list in the
EmployeeStatistics class, so the obvious solution would be to expose that private list:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public List<Employee> Employees => _employees;
}

Now, we can complete the Count method logic:

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<
public class EmployeeStatistics
{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers () =>
_empManager.Employees.Count(emp => emp.Gender == Gender.Female && emp.Position == Position.Manager);
}
Even though this will work just fine, this is not what we consider a good code and it violates the DIP.

How is that?

Well, first of all, our EmployeeStatistics class has a strong relation (coupled) to the EmployeeManager class and we
can’t send any other object in the EmployeeStatistics constructor except the EmployeeManager object. The
second problem is that we are using the public property from the low-level class inside the high-level class. By doing so, our
low-level class can’t change its way of keeping track of employees. If we want to change its behavior to use a dictionary
instead of a list, we need to change the EmployeeStatistics class behavior for sure. And that’s something we want to
avoid if possible.

Making Our Code Better by implementing the Dependency Inversion Principle

What we want is to decouple our two classes so the both of them depend on abstraction.

So, the first thing we need to do is to create the IEmployeeSearchable interface:

public interface IEmployeeSearchable


{
IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position);
}

Then, let’s modify the EmployeeManager class:

public class EmployeeManager: IEmployeeSearchable


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position)
=> _employees.Where(emp => emp.Gender == gender && emp.Position == position);
}

Finally, we can modify the EmployeeStatistics class:

public class EmployeeStatistics


{
private readonly IEmployeeSearchable _emp;
public EmployeeStatistics(IEmployeeSearchable emp)
{
_emp = emp;
}
public int CountFemaleManagers() =>
_emp.GetEmployeesByGenderAndPosition(Gender.Female, Position.Manager).Count();
}

This looks much better now and it’s implemented by DIP rules. Now, our EmployeeStatistics class is not dependent
on the lower-level class and the EmployeeManager class can change its behavior about storing employees as well.

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<
Finally, we can check the result by modifying Program.cs class:

class Program
{
static void Main(string[] args)
{
var empManager = new EmployeeManager();
empManager.AddEmployee(new Employee { Name = "Leen", Gender = Gender.Female, Position = Position.Manager });
empManager.AddEmployee(new Employee { Name = "Mike", Gender = Gender.Male, Position = Position.Administrator
});
var stats = new EmployeeStatistics(empManager);
Console.WriteLine($"Number of female managers in our company is: {stats.CountFemaleManagers()}");
}
}

Benefits of Implementing the Dependency Inversion Principle

Reducing the number of dependencies among modules is an important part of the process of creating an application. This is
something that we get if we implement DIP correctly. Our classes are not tightly coupled with the lower-tier objects and we
can easily reuse the logic from the high-tier modules.
So, the main reason why DIP is so important is the modularity and reusability of the application modules.

It is also important to mention that changing already implemented modules is risky. By depending on abstraction and not on
a concrete implementation, we can reduce that risk by not having to change high-level modules in our project.

Finally, DIP when applied correctly gives us the flexibility and stability at the level of the entire architecture of our
application. Our application will be able to evolve more securely and become stable and robust.

Conclusion

So to sum up, the Dependency Inversion Principle is the last part of the SOLID principles which introduce an abstraction
between high and low-level components inside our project to remove dependencies between them.

If someone asks: „Should I put an effort to implement the DIP into my code?“, our answer would be: „Yes you should“.
Loosely coupled code and reusable components should be our goal and responsibility when developing software
applications.

SOLID Principles in C#

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

SOLID principles represent a set of principles that, if implemented properly should improve our code significantly.
As with any other principle in life, we can misuse and overuse every SOLID principle to the point of being
counterproductive. Instead of getting an understandable, maintainable, and flexible code, we could end up with the code
that’s in worse shape than without SOLID.

So, careful consideration and implementing these SOLID principles only where needed is the key to a clean codebase.

SOLID is a mnemonic acronym and each of the letters in it stands for:

 S – Single Responsibility Principle


 O – Open/Closed Principle
 L – Liskov Substitution Principle
 I – Interface Segregation Principle
 D – Dependency Inversion Principle

The source code for this series of articles can be found in this GitHub repo. You can switch to different branches to get to
the different parts of the series.

We hope these articles will help you discern when and how to implement these principles the right way.

SOLID Principles in C# – Single Responsibility Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 8

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!
While developing a project, we strive to write maintainable and readable code (besides the working part �). To accomplish
this, each and every class should do its own task and do it well.

Yes, it is quite important for a class to have no more than one task. If it does, our code becomes harder to maintain, due to
the fact that it is responsible for the execution of several different tasks and thus being more likely to change in the future.

This is completely opposite of what the Single Responsibility Principle (SRP) states.

The Single Responsibility Principle states that our classes should have only one reason to change or in other words, it
should have only one responsibility.

Simple as that.

In this article, we are going to show you, through an example, how to create a code that abides by SRP rules. We will start
with the code which isn’t SRP compliant and then refactor it to be in accordance with SRP. To finish our example, we will
add a bit of reusability to our code, because we don’t want to repeat ourselves while coding.

To download the source code for this project, check out the Single Responsibility Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

So, let’s start.

Creating the Initial Project

We are going to start with a simple console application.

Imagine if we have a task to create a work report feature that, once created, can be saved to a file and perhaps uploaded to
the cloud or used for some other purpose.
So we are going to start with a simple model class:

public class WorkReportEntry


{
public string ProjectCode { get; set; }
public string ProjectName { get; set; }
public int SpentHours { get; set; }
}

The next step is creating a WorkReport class which will handle all the required features for our project:

public class WorkReport


{
private readonly List<WorkReportEntry> _entries;
public WorkReport()
{
_entries = new List<WorkReportEntry>();
}
public void AddEntry(WorkReportEntry entry) => _entries.Add(entry);
public void RemoveEntryAt(int index) => _entries.RemoveAt(index);
public override string ToString() =>
string.Join(Environment.NewLine, _entries.Select(x => $"Code: {x.ProjectCode}, Name: {x.ProjectName}, Hours:
{x.SpentHours}"));
}

In this class, we are keeping track of our work report entries by adding and removing them to/from a list. Furthermore, we
are just overriding ToString() method to adjust it to our requirements.

Because we have our WorkReport class, it is quite fine to add our additional features to it, like saving to a file:

public class WorkReport


{
private readonly List<WorkReportEntry> _entries;
public WorkReport()
{
_entries = new List<WorkReportEntry>();
}
public void AddEntry(WorkReportEntry entry) => _entries.Add(entry);
public void RemoveEntryAt(int index) => _entries.RemoveAt(index);
public void SaveToFile(string directoryPath, string fileName)
{
if(!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
File.WriteAllText(Path.Combine(directoryPath, fileName), ToString());
}
public override string ToString() =>
string.Join(Environment.NewLine, _entries.Select(x => $"Code: {x.ProjectCode}, Name: {x.ProjectName}, Hours:
{x.SpentHours}"));
}

Problems With This Code

We can add even more features in this class, like the Load or UploadToCloud methods because they are all related to our
WorkReport, but, just because we can doesn’t mean we have to do it.

Right now, there is one issue with the WorkReport class.

It has more than one responsibility.


Its job is not only to keep track of our work report entries but to save the entire work report to a file. This means that we are
violating the SRP and our class has more than one reason to change in the future.

The first reason to change this class is if we want to modify the way we keep track of our entries. But if we want to save a
file in a different way, that is entirely a new reason to change our class. And imagine what this class would look like if we
added additional functionalities to it. We would have so many unrelated code parts in a single class.

So, in order to avoid that, let’s refactor the code.

Refactoring Towards SRP

The first thing we need to do is to separate the part of our code that is unlike others. In our case, that is obviously the
SaveToFile method, so we are going to move it to another class which is more appropriate:

public class FileSaver


{
public void SaveToFile(string directoryPath, string fileName, WorkReport report)
{
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
File.WriteAllText(Path.Combine(directoryPath, fileName), report.ToString());
}
}
}
public class WorkReport
{
private readonly List<WorkReportEntry> _entries;
public WorkReport()
{
_entries = new List<WorkReportEntry>();
}
public void AddEntry(WorkReportEntry entry) => _entries.Add(entry);
public void RemoveEntryAt(int index) => _entries.RemoveAt(index);
public override string ToString() =>
string.Join(Environment.NewLine, _entries.Select(x => $"Code: {x.ProjectCode}, Name: {x.ProjectName}, Hours:
{x.SpentHours}"));
}
In this case, we have separated our responsibilities in two classes. The WorkReport class is now responsible for keeping
track of work report entries and the FileSaver class is responsible for saving a file.

Having done this, we have separated the concerns of each class thus making them more readable and maintainable as well.
As a result, if we want to change how we save a file, we only have one reason to do that and one place to do it, which is the
FileSaver class.

We can check that everything is working as it supposed to do:

class Program
{
static void Main(string[] args)
{
var report = new WorkReport();
report.AddEntry(new WorkReportEntry { ProjectCode = "123Ds", ProjectName = "Project1", SpentHours = 5 });
report.AddEntry(new WorkReportEntry { ProjectCode = "987Fc", ProjectName = "Project2", SpentHours = 3 });
Console.WriteLine(report.ToString());
var saver = new FileSaver();
saver.SaveToFile(@"Reports", "WorkReport.txt", report);
}
}
Making the Code Even Better

If we look at our SaveToFile method, we see that it does its job which is saving a work report to a file, but can it do it
even better? This method is tightly coupled with the WorkReport class, but what if we want to create a Scheduler
class that keeps track of its scheduled tasks? We would still like to save it to a file.

Well, in that case, we are going to create some changes to our code:

public interface IEntryManager<T>


{
void AddEntry(T entry);
void RemoveEntryAt(int index);
}
The only change to the WorkReport class is to implement this interface:

public class WorkReport: IEntryManager<WorkReportEntry>

Finally, we have to change the SaveToFile method signature:

public void SaveToFile<T>(string directoryPath, string fileName, IEntryManager<T> workReport)

After these modifications, we are going to have the same result, but now if we have a task to implement Scheduler, it is
going to be quite simple to implement that:

public class ScheduleTask


{
public int TaskId { get; set; }
public string Content { get; set; }
public DateTime ExecuteOn { get; set; }
}
public class Scheduler : IEntryManager<ScheduleTask>
{
private readonly List<ScheduleTask> _scheduleTasks;
public Scheduler()
{
_scheduleTasks = new List<ScheduleTask>();
}
public void AddEntry(ScheduleTask entry) => _scheduleTasks.Add(entry);
public void RemoveEntryAt(int index) => _scheduleTasks.RemoveAt(index);
public override string ToString() =>
string.Join(Environment.NewLine, _scheduleTasks.Select(x => $"Task with id: {x.TaskId} with content: {x.Content} is going to
be executed on: {x.ExecuteOn}"));
}
class Program
{
static void Main(string[] args)
{
var report = new WorkReport();
report.AddEntry(new WorkReportEntry { ProjectCode = "123Ds", ProjectName = "Project1", SpentHours = 5 });
report.AddEntry(new WorkReportEntry { ProjectCode = "987Fc", ProjectName = "Project2", SpentHours = 3 });
var scheduler = new Scheduler();
scheduler.AddEntry(new ScheduleTask { TaskId = 1, Content = "Do something now.", ExecuteOn =
DateTime.Now.AddDays(5) });
scheduler.AddEntry(new ScheduleTask { TaskId = 2, Content = "Don't forget to...", ExecuteOn = DateTime.Now.AddDays(2)
});
Console.WriteLine(report.ToString());
Console.WriteLine(scheduler.ToString());
var saver = new FileSaver();
saver.SaveToFile(@"Reports", "WorkReport.txt", report);
saver.SaveToFile(@"Schedulers", "Schedule.txt", scheduler);
}
}

After we execute this code, we will have our file saved in a required location on a defined schedule.

We are going to leave it at that. Now every class we have is responsible for one thing and one thing only.

Benefits of Single Responsibility Principle

Our code has improved in several ways by implementing SRP. The first one being that it has become less complex. Because
we are trying to accomplish only one task in our class, they have become free of clutter and simple to read. As we reduce
code complexity, our code becomes readable and therefore maintainable.
As we could see from our example, if our class does its job well, we can reuse its logic in a project. Furthermore, with such
a code, testing becomes easier as well.

When we implement SRP in our code, our methods become highly related (coherent). It means that different methods are
joined to do one thing and to do it well.

Finally, our classes are less dependent on each other (decoupled) which is one of the most important things to achieve while
working on a project.

Potential Downsides of SRP

There is no strict rule which states what is that „one reason to change“ in our class. Everyone interprets this subjectively or
rather how he/she feels it should be implemented. The rules are not clear to where we should draw the line, so we can
potentially find different „right ways“ to implement the same feature.

But still, the bottom line is that no matter what someone thinks about what reason to change is, we should all strive to write
readable and maintainable code thus implementing Single Responsibility Principle in our own way.

One of the potential downsides is that in projects that are already written, is difficult to implement SRP. We don’t say that it
is not possible, just that it will take longer and take more resources as well.

Implementing SRP leads to writing compact classes with tiny methods as well. And on a first look, this looks great. But
having one big class decomposed into a lot of small classes creates an organizational risk. If those classes are not organized
and grouped well, it could actually increase the amount of work needed to change a system and to understand it which is
opposite of what we wanted to achieve in the first place.

Conclusion
Implementing the Single Responsibility Principle should be always in our mind while writing code. It can be tough to write
the code according to SRP right from scratch, but you can write your code iteratively and return to the parts that need
attention later. Refactoring is a common practice and nobody writes code perfectly right away. So refactor towards the SRP
later if you are not sure which class does what at that moment. It will help not only you but the other developers that need to
maintain your code later as well.

SOLID Principles in C# – Open Closed Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 23

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

The Open Closed Principle (OCP) is the SOLID principle which states that the software entities (classes or methods) should
be open for extension but closed for modification.

But what does this really mean?

Basically, we should strive to write a code that doesn’t require modification every time a customer changes its request.
Providing such a solution where we can extend the behavior of a class (with that additional customer’s request) and not
modify that class, should be our goal most of the time.

In this article, we will show you how to write the code by following the Open Closed Principle with two different examples.
Initially, none of the examples will obey the OCP rules, but right after the initial development, we are going to refactor the
code using the OCP.
To download the source code for this project, check out the Open Closed Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

So, let’s jump right into it.

Salary Calculator Example

Let’s imagine that we have a task where we need to calculate the total cost of all the developer salaries in a single company.
Of course, we are going to make this example simple and focus on the required topic.

To get started, we are going to create the model class first:

public class DeveloperReport


{
public int Id { get; set; }
public string Name { get; set; }
public string Level { get; set; }
public int WorkingHours { get; set; }
public double HourlyRate { get; set; }
}

Once we’ve created our model, we can transition to the salary calculation feature:

public class SalaryCalculator


{
private readonly IEnumerable<DeveloperReport> _developerReports;
public SalaryCalculator(List <DeveloperReport> developerReports)
{
_developerReports = developerReports;
}
public double CalculateTotalSalaries()
{
double totalSalaries = 0D ;
foreach (var devReport in _developerReports)
{
totalSalaries += devReport.HourlyRate * devReport.WorkingHours;
}
return totalSalaries;
}
}

Now, all we have to do is to provide some data for this class and we are going to have our total costs calculated:

static void Main(string[] args)


{
var devReports = new List<DeveloperReport>
{
new DeveloperReport {Id = 1, Name = "Dev1", Level = "Senior developer", HourlyRate = 30.5, WorkingHours = 160 },
new DeveloperReport {Id = 2, Name = "Dev2", Level = "Junior developer", HourlyRate = 20, WorkingHours = 150 },
new DeveloperReport {Id = 3, Name = "Dev3", Level = "Senior developer", HourlyRate = 30.5, WorkingHours = 180 }
};
var calculator = new SalaryCalculator(devReports);
Console.WriteLine($"Sum of all the developer salaries is {calculator.CalculateTotalSalaries()} dollars");
}

Our result should be:


So, all of this is working great, but now our boss comes to our office and says that we need a different calculation for the
senior and junior developers. The senior developers should have a bonus of 20% on a salary.

Of course, to satisfy this requirement, we are going to modify our CalculateTotalSalaries method like this:

public double CalculateTotalSalaries()


{
double totalSalaries = 0D;
foreach (var devReport in _developerReports)
{
if(devReport.Level == "Senior developer")
{
totalSalaries += devReport.HourRate * devReport.WorkingHours * 1.2;
}
else
{
totalSalaries += devReport.HourRate * devReport.WorkingHours;
}
}
return totalSalaries;
}
Even though this solution is going to give us the correct result, this is not an optimal solution.

Why is that?

Mainly, because we had to modify our existing class behavior which worked perfectly. Another thing is that if our boss
comes again and ask us to modify calculation for the junior dev’s as well, we would have to change our class again. This is
totally against of what OCP stands for.

It is obvious that we need to change something in our solution, so, let’s do it.

Better Salary Calculator Example – OCP implemented

To create a code that abides by the Open Closed Principle, we are going to create an abstract class first:

public abstract class BaseSalaryCalculator


{
protected DeveloperReport DeveloperReport { get; private set; }
public BaseSalaryCalculator(DeveloperReport developerReport)
{
DeveloperReport = developerReport;
}
public abstract double CalculateSalary();
}

As a continuation, we are going to create two classes which will inherit from the BaseSalaryCalculator class. Because it is
obvious that our calculation depends on the developer’s level, we are going to create our new classes in that manner:

public class SeniorDevSalaryCalculator : BaseSalaryCalculator


{
public SeniorDevSalaryCalculator(DeveloperReport report)
:base(report)
{
}
public override double CalculateSalary() => DeveloperReport.HourlyRate * DeveloperReport.WorkingHours * 1.2;
}
public class JuniorDevSalaryCalculator : BaseSalaryCalculator
{
public JuniorDevSalaryCalculator(DeveloperReport developerReport)
:base(developerReport)
{
}
public override double CalculateSalary() => DeveloperReport.HourlyRate * DeveloperReport.WorkingHours;
}

Excellent. Now we can modify the SalaryCalculator class:

public class SalaryCalculator


{
private readonly IEnumerable<BaseSalaryCalculator> _developerCalculation;
public SalaryCalculator(IEnumerable<BaseSalaryCalculator> developerCalculation)
{
_developerCalculation = developerCalculation;
}
public double CalculateTotalSalaries()
{
double totalSalaries = 0D;
foreach (var devCalc in _developerCalculation)
{
totalSalaries += devCalc.CalculateSalary();
}
return totalSalaries;
}
}

This looks so much better because we won’t have to change any of our current classes if our boss comes with another
request about the intern payment calculation or any other as well.

All we have to do now is to add another class with its own calculation logic. So basically, our SalaryCalculator class
is now closed for modification and opened for an extension, which is exactly what OCP states.

To finish this example, let’s modify the Program.cs class:

class Program
{
static void Main(string[] args)
{
var devCalculations = new List<BaseSalaryCalculator>
{
new SeniorDevSalaryCalculator(new DeveloperReport {Id = 1, Name = "Dev1", Level = "Senior developer", HourlyRate =
30.5, WorkingHours = 160 }),
new JuniorDevSalaryCalculator(new DeveloperReport {Id = 2, Name = "Dev2", Level = "Junior developer", HourlyRate =
20, WorkingHours = 150 }),
new SeniorDevSalaryCalculator(new DeveloperReport {Id = 3, Name = "Dev3", Level = "Senior developer", HourlyRate =
30.5, WorkingHours = 180 })
};
var calculator = new SalaryCalculator(devCalculations);
Console.WriteLine($"Sum of all the developer salaries is {calculator.CalculateTotalSalaries()} dollars");
}
}

Awesome. We have finished our first example.

Let’s start with another one.

Filtering Computer Monitors Example

Let’s imagine for a moment that we have a task to write an application which gives us all the required information about
computer monitors in our shop, based on different criteria. We will introduce only two criteria here, the type of monitors
and the screen size. So let’s start with that:

public enum MonitorType


{
OLED,
LCD,
LED
}
public enum Screen
{
WideScreen,
CurvedScreen
}

To continue, we are going to create a simple model class:


public class ComputerMonitor
{
public string Name { get; set; }
public MonitorType Type { get; set; }
public Screen Screen { get; set; }
}

Now, we need to implement our filtering functionality. For example, we want to filter by the monitor types:

public class MonitorFilter


{
public List<ComputerMonitor> FilterByType(IEnumerable<ComputerMonitor> monitors, MonitorType type) =>
monitors.Where(m => m.Type == type).ToList();
}

And finally the Program.cs class:

class Program
{
static void Main(string[] args)
{
var monitors = new List<ComputerMonitor>
{
new ComputerMonitor { Name = "Samsung S345", Screen = Screen.CurvedScreen, Type = MonitorType.OLED },
new ComputerMonitor { Name = "Philips P532", Screen = Screen.WideScreen, Type = MonitorType.LCD },
new ComputerMonitor { Name = "LG L888", Screen = Screen.WideScreen, Type = MonitorType.LED },
new ComputerMonitor { Name = "Samsung S999", Screen = Screen.WideScreen, Type = MonitorType.OLED },
new ComputerMonitor { Name = "Dell D2J47", Screen = Screen.CurvedScreen, Type = MonitorType.LCD }
};
var filter = new MonitorFilter();
var lcdMonitors = filter.FilterByType(monitors, MonitorType.LCD);
Console.WriteLine("All LCD monitors");
foreach (var monitor in lcdMonitors)
{
Console.WriteLine($"Name: {monitor.Name}, Type: {monitor.Type}, Screen: {monitor.Screen}");
}
}
}

This is going to work just fine. But, after a couple of days, we receive a request that our customers want to have the filter by
Screen functionality as well.

So this should be quite simple, shouldn’t it?

Let’s just change the MonitorFilter class:

public class MonitorFilter


{
public List<ComputerMonitor> FilterByType(IEnumerable<ComputerMonitor> monitors, MonitorType type) =>
monitors.Where(m => m.Type == type).ToList();
public List<ComputerMonitor> FilterByScreen(IEnumerable<ComputerMonitor> monitors, Screen screen) =>
monitors.Where(m => m.Screen == screen).ToList();
}
Even though this is going to give us the correct result, we have a problem because we have to modify our existing class.
And what if we receive another request to filter all the monitors by type and screen together? We all see where this lead us,
towards breaking the OCP. We are not extending our MonitorFilter class but modifying it.

So, in order to avoid existing class modification, let’s try another approach.

Creating a couple of interfaces is going to be our first step:

public interface ISpecification<T>


{
bool isSatisfied(T item);
}
public interface IFilter<T>
{
List<T> Filter(IEnumerable<T> monitors, ISpecification<T> specification);
}

With the ISpecification interface, we can determine whether or not our criterion is satisfied and we can send it to the
Filter method from the IFilter interface.

To continue on, we are going to create a separate class for the monitor type specification:

public class MonitorTypeSpecification: ISpecification<ComputerMonitor>


{
private readonly MonitorType _type;
public MonitorTypeSpecification(MonitorType type)
{
_type = type;
}
public bool isSatisfied(ComputerMonitor item) => item.Type == _type;
}

After this modification, all we have to do is to write a class that implements IFilter interface. But because we already have
the MonitorFilter class, we are just going to modify it:

public class MonitorFilter : IFilter<ComputerMonitor>


{
public List<ComputerMonitor> Filter(IEnumerable<ComputerMonitor> monitors, ISpecification<ComputerMonitor>
specification) =>
monitors.Where(m => specification.isSatisfied(m)).ToList();
}

Finally, let’s modify the Program.cs class:

var filter = new MonitorFilter();


var lcdMonitors = filter.Filter(monitors, new MonitorTypeSpecification(MonitorType.LCD));
Console.WriteLine("All LCD monitors");
foreach (var monitor in lcdMonitors)
{
Console.WriteLine($"Name: {monitor.Name}, Type: {monitor.Type}, Screen: {monitor.Screen}");
}

The result should be the same:


Additional Filter Requests

Right now, we are perfectly able to extend our MonitorFilter class without any further modification. So, if now we
have to implement the filter by screen feature, for example only widescreen monitors, we can do it with a new class:

public class ScreenSpecification : ISpecification<ComputerMonitor>


{
private readonly Screen _screen;
public ScreenSpecification(Screen screen)
{
_screen = screen;
}
public bool isSatisfied(ComputerMonitor item) => item.Screen == _screen;
}

And, we can make a call towards the MonitorFilter class:

Console.WriteLine("All WideScreen Monitors");


var wideScreenMonitors = filter.Filter(monitors, new ScreenSpecification(Screen.WideScreen));
foreach (var monitor in wideScreenMonitors)
{
Console.WriteLine($"Name: {monitor.Name}, Type: {monitor.Type}, Screen: {monitor.Screen}");
}

Excellent.

With this project structure, we can even extend our filtering criterion to, for example, only OLED and widescreen monitors.
All we have to do is to create another specification class.

Why Should We Implement the Open Closed Principle

By implementing the OCP we are lowering the chance of producing bugs in our project.

For example, if we have a fully working and already tested class in production, by extending it instead of changing it, we
would definitely have a lesser impact on the rest of the system.

Therefore, we introduce another class to extend the behavior of the main class thus avoid the existing functionality
modification that other classes may rely upon.

Another benefit is that we only have to test and deploy the new features, which wouldn’t be the case if we had to change
existing functionality. Furthermore, if we decide that we don’t need this feature anymore (sometime in the future), all we
have to do is to revert just newly implemented change and that’s it.

Conclusion

We’ve seen how the OCP can help us create better and more maintainable code. But, as with everything else, we should be
cautious when implementing this principle.

Sometimes it’s just impossible to extend our class and all we are left to do is to modify existing functionality. We shouldn’t
be afraid to do it, it is quite normal, but at least we should try to make those changes as discrete as they can be.
So, we should develop our applications with the OCP in mind and we should strive to write extendable code as much as we
can because it leads to the maintainable, scalable and testable codebase.

SOLID Principles in C# – Liskov Substitution Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 11

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

The Liskov Substitution Principle (LSP) states that child class objects should be able to replace parent class objects without
compromising application integrity. What this means essentially, is that we should put an effort to create such derived class
objects which can replace objects of the base class without modifying its behavior. If we don’t, our application might end up
being broken.

Does this make sense to you?

To make things clear, we are going to use a simple „Sum Calculator“ example, which will help us to understand how to
implement the LSP better.

To download the source code for this project, check out the Liskov Substitution Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

Initial Project
In this example, we are going to have an array of numbers and a base functionality to sum all the numbers from that array.
But let’s say we need to sum just even or just odd numbers.

How would we implement that? Let’s see one way to do it:

public class SumCalculator


{
protected readonly int[] _numbers;
public SumCalculator(int[] numbers)
{
_numbers = numbers;
}
public int Calculate() => _numbers.Sum();
}
public class EvenNumbersSumCalculator: SumCalculator
{
public EvenNumbersSumCalculator(int[] numbers)
:base(numbers)
{
}
public new int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}

Now if we test this solution, whether we calculate the sum of all the numbers or the sum of just even numbers, we are going
to get the correct result for sure:

class Program
{
static void Main(string[] args)
{
var numbers = new int[] { 5, 7, 9, 8, 1, 6, 4 };
SumCalculator sum = new SumCalculator(numbers);
Console.WriteLine($"The sum of all the numbers: {sum.Calculate()}");
Console.WriteLine();
EvenNumbersSumCalculator evenSum = new EvenNumbersSumCalculator(numbers);
Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");
}
}

The result is:

Creating a Better Solution

As we can see, this is working just fine. But what is wrong with this solution then?

Why are we trying to fix it?


Well, as we all know, if a child class inherits from a parent class, then the child class is a parent class. Having that in mind,
we should be able to store a reference to an EvenNumbersSumCalculator as a SumCalculator variable and
nothing should change. So, let’s check that out:

SumCalculator evenSum = new EvenNumbersSumCalculator(numbers);


Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");

As we can see, we are not getting the expected result because our variable evenSum is of type SumCalculator which is
a higher order class (a base class). This means that the Count method from the SumCalculator will be executed. So,
this is not right, obviously, because our child class is not behaving as a substitute for the parent class.

Luckily, the solution is quite simple. All we have to do is to implement small modifications to both of our classes:

public class SumCalculator


{
protected readonly int[] _numbers;
public SumCalculator(int[] numbers)
{
_numbers = numbers;
}
public virtual int Calculate() => _numbers.Sum();
}
public class EvenNumbersSumCalculator: SumCalculator
{
public EvenNumbersSumCalculator(int[] numbers)
:base(numbers)
{
}
public override int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}

As a result, when we start our solution, everything works as expected and the sum of even numbers is 18 again.

So, let’s explain this behavior. If we have a child object reference stored in a parent object variable and call the
Calculate method, the compiler will use the Calculate method of the parent class. But right now because the
Calculate method is defined as „virtual“ and is overridden in the child class, that method in the child class will be used
instead.

Implementing the Liskov Substitution Principle

Still, the behavior of our derived class has changed and it can’t replace the base class. So we need to upgrade this solution
by introducing the Calculator abstract class:

public abstract class Calculator


{
protected readonly int[] _numbers;
public Calculator(int[] numbers)
{
_numbers = numbers;
}
public abstract int Calculate();
}

Then we have to change our other classes:

public class SumCalculator : Calculator


{
public SumCalculator(int[] numbers)
:base(numbers)
{
}
public override int Calculate() => _numbers.Sum();
}
public class EvenNumbersSumCalculator: Calculator
{
public EvenNumbersSumCalculator(int[] numbers)
:base(numbers)
{
}
public override int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}

Excellent. Now we can start making calls towards these classes:

class Program
{
static void Main(string[] args)
{
var numbers = new int[] { 5, 7, 9, 8, 1, 6, 4 };
Calculator sum = new SumCalculator(numbers);
Console.WriteLine($"The sum of all the numbers: {sum.Calculate()}");
Console.WriteLine();
Calculator evenSum = new EvenNumbersSumCalculator(numbers);
Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");
}
}

We will again have the same result, 40 for all the numbers and 18 for the even numbers. But now, we can see that we can
store any subclass reference into a base class variable and the behavior won’t change which is the goal of LSP.

What We Gain By Implementing the LSP

By implementing the LSP, we are keeping our functionality intact and still having our subclasses act as a substitute to a base
class.

Also, we encourage the code reusability by implementing the LCP and having better project maintenance as well.

Conclusion

We can see that implementing the LSP is not that complicated but just the opposite. Most of us probably already
implemented this principle many times in our code without knowing its name because in the object-oriented world
Polymorphism is quite a big thing.

SOLID Principles in C# – Interface Segregation Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 7


Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

The Interface Segregation Principle states that no client should be forced to depend on methods it does not use. So, this is
the basic definition which we can read in many different articles, but what does this really mean?

Let’s imagine that we are starting a new feature on our project. We start with some code and from that code, an interface
emerges with the required declarations. Soon after, the customer decides that they want another feature that is similar to the
previous one and we decide to implement the same interface in another class. But now, as a consequence, we don’t need all
the methods from that interface, just some of them. Of course, we have to implement all the methods, which we shouldn’t
have to, and that’s the problem and where the ISP helps us a lot.

Basically, the ISP states that we should reduce code objects down to the smallest required implementation thus creating
interfaces with only required declarations. As a result, an interface that has a lot of different declarations should be split up
into smaller interfaces.

Let’s see how this looks in an example.

To download the source code for this project, check out the Interface Segregation Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

Starting Example
There are vehicles that we can drive, and there are those we can fly with. But there are cars we can drive and fly (yes those
are on sale). So, we want to create a code structure which supports all the actions for a single vehicle, and we are going to
start with an interface:

public interface IVehicle


{
void Drive();
void Fly();
}

Now if we want to develop a behavior for a multifunctional car, this interface is going to be perfect for us:

public class MultiFunctionalCar : IVehicle


{
public void Drive()
{
//actions to start driving car
Console.WriteLine("Drive a multifunctional car");
}
public void Fly()
{
//actions to start flying
Console.WriteLine("Fly a multifunctional car");
}
}

This is working great. Our interface covers all the required actions.
But now, we want to implement the Car class and the Airplane class as well:

public class Car : IVehicle


{
public void Drive()
{
//actions to drive a car
Console.WriteLine("Driving a car");
}
public void Fly()
{
throw new NotImplementedException();
}
}
public class Airplane : IVehicle
{
public void Drive()
{
throw new NotImplementedException();
}
public void Fly()
{
//actions to fly a plane
Console.WriteLine("Flying a plane");
}
}
Now we can see what the problem with the IVehicle interface is. It contains only one required declaration per each class.
The other method, which is not required, is implemented to throw an exception. That is a bad idea because we should be
writing our code to do something and not just to throw exceptions. Furthermore, we would have to put an additional effort
to document our class so that users know why they shouldn’t be using the not implemented method. A really bad idea.

So, in order to fix this problem, we are going to do some refactoring to our code and write it in accordance to ISP.

Implementing the ISP In the Current Solution

The first thing we are going to do is to divide our IVehicle interface:

public interface ICar


{
void Drive();
}
public interface IAirplane
{
void Fly();
}

As a result, our classes can implement only the methods they need:

public class Car : ICar


{
public void Drive()
{
//actions to drive a car
Console.WriteLine("Driving a car");
}
}
public class Airplane : IAirplane
{
public void Fly()
{
//actions to fly a plane
Console.WriteLine("Flying a plane");
}
}
public class MultiFunctionalCar : ICar, IAirplane
{
public void Drive()
{
//actions to start driving car
Console.WriteLine("Drive a multifunctional car");
}
public void Fly()
{
//actions to start flying
Console.WriteLine("Fly a multifunctional car");
}
}

We can even use a higher level interface if we want in a situation where a single class implements more than one interface:

public interface IMultiFunctionalVehicle : ICar, IAirplane


{
}

Once we have our higher level interface, we can implement it in different ways. The first one is to implement the required
methods:

public class MultiFunctionalCar : IMultiFunctionalVehicle


{
public void Drive()
{
//actions to start driving car
Console.WriteLine("Drive a multifunctional car");
}
public void Fly()
{
//actions to start flying
Console.WriteLine("Fly a multifunctional car");
}
}

Or if we already have implemented the Car class and the Airplane class, we can use them inside our class by using the
decorator pattern:

public class MultiFunctionalCar : IMultiFunctionalVehicle


{
private readonly ICar _car;
private readonly IAirplane _airplane;
public MultiFunctionalCar(ICar car, IAirplane airplane)
{
_car = car;
_airplane = airplane;
}
public void Drive()
{
_car.Drive();
}
public void Fly()
{
_airplane.Fly();
}
}

What are the Benefits of the Interface Segregation Principle

We can see from the example above, that smaller interface is a lot easier to implement due to not having to implement
methods that our class doesn’t need.

Of course, due to the simplicity of our example, we can make a single interface with a single method inside it. But in real-
world projects, we often come up with an interface with multiple methods, which is perfectly normal as long as those
methods are highly related to each other. Therefore, we make sure that our class needs all these actions to complete its task.

Another benefit is that the Interface Segregation Principle increases the readability and maintainability of our code. We are
reducing our class implementation only to required actions without any additional or unnecessary code.

Conclusion
To sum this article up, we should put an effort into creating smaller interfaces while developing our project. Yes, we may
end up with a lot of different interfaces in the end but from our point of view, this is much better than having a few large
interfaces that can force us to implement non-required methods in our classes.

SOLID Principles in C# – Dependency Inversion Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 4

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

The basic idea behind the Dependency Inversion Principle is that we should create the higher-level modules with its
complex logic in such a way to be reusable and unaffected by any change from the lower-level modules in our application.
To achieve this kind of behavior in our apps, we introduce abstraction which decouples higher from lower-level modules.

Having this idea in mind the Dependency Inversion Principle states that

 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.

We are going to make all of this easier to understand with an example and additional explanations.

To download the source code for this project, check out the Dependency Inversion Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.
What are the High-Level and Low-Level Modules

The high-level modules describe those operations in our application that have more abstract nature and contain more
complex logic. These modules orchestrate low-level modules in our application.

The low-level modules contain more specific individual components focusing on details and smaller parts of the application.
These modules are used inside the high-level modules in our app.

What we need to understand when talking about DIP and these modules is that both, the high-level and low-level modules,
depend on abstractions. We can find different opinions about if the DIP inverts dependency between high and low-level
modules or not. Some agree with the first opinion and others prefer the second. But the common ground is that the DIP
creates a decoupled structure between high and low-level modules by introducing abstraction between them.

Dependency Injection is one way of implementing the Dependency Inversion Principle.

Example Which Violates DIP

Let’s start by creating two enumerations and one model class:

public enum Gender


{
Male,
Female
}
public enum Position
{
Administrator,
Manager,
Executive
}
public class Employee
{
public string Name { get; set; }
public Gender Gender { get; set; }
public Position Position { get; set; }
}

To continue, we are going to create one low-level class which keeps (in a simplified way) track of our employees:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
}

Furthermore, we are going to create a higher-level class to perform some kind of statistical analysis on our employees:

public class EmployeeStatistics


{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers()
{
//logic goes here
}
}

With this kind of structure in our EmployeeManager class, we can’t make use of the _employess list in the
EmployeeStatistics class, so the obvious solution would be to expose that private list:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public List<Employee> Employees => _employees;
}
Now, we can complete the Count method logic:

public class EmployeeStatistics


{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers () =>
_empManager.Employees.Count(emp => emp.Gender == Gender.Female && emp.Position == Position.Manager);
}

Even though this will work just fine, this is not what we consider a good code and it violates the DIP.

How is that?

Well, first of all, our EmployeeStatistics class has a strong relation (coupled) to the EmployeeManager class and we
can’t send any other object in the EmployeeStatistics constructor except the EmployeeManager object. The
second problem is that we are using the public property from the low-level class inside the high-level class. By doing so, our
low-level class can’t change its way of keeping track of employees. If we want to change its behavior to use a dictionary
instead of a list, we need to change the EmployeeStatistics class behavior for sure. And that’s something we want to
avoid if possible.

Making Our Code Better by implementing the Dependency Inversion Principle

What we want is to decouple our two classes so the both of them depend on abstraction.
So, the first thing we need to do is to create the IEmployeeSearchable interface:

public interface IEmployeeSearchable


{
IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position);
}

Then, let’s modify the EmployeeManager class:

public class EmployeeManager: IEmployeeSearchable


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position)
=> _employees.Where(emp => emp.Gender == gender && emp.Position == position);
}

Finally, we can modify the EmployeeStatistics class:

public class EmployeeStatistics


{
private readonly IEmployeeSearchable _emp;
public EmployeeStatistics(IEmployeeSearchable emp)
{
_emp = emp;
}
public int CountFemaleManagers() =>
_emp.GetEmployeesByGenderAndPosition(Gender.Female, Position.Manager).Count();
}

This looks much better now and it’s implemented by DIP rules. Now, our EmployeeStatistics class is not dependent
on the lower-level class and the EmployeeManager class can change its behavior about storing employees as well.

Finally, we can check the result by modifying Program.cs class:

class Program
{
static void Main(string[] args)
{
var empManager = new EmployeeManager();
empManager.AddEmployee(new Employee { Name = "Leen", Gender = Gender.Female, Position = Position.Manager });
empManager.AddEmployee(new Employee { Name = "Mike", Gender = Gender.Male, Position = Position.Administrator
});
var stats = new EmployeeStatistics(empManager);
Console.WriteLine($"Number of female managers in our company is: {stats.CountFemaleManagers()}");
}
}
Benefits of Implementing the Dependency Inversion Principle

Reducing the number of dependencies among modules is an important part of the process of creating an application. This is
something that we get if we implement DIP correctly. Our classes are not tightly coupled with the lower-tier objects and we
can easily reuse the logic from the high-tier modules.

So, the main reason why DIP is so important is the modularity and reusability of the application modules.

It is also important to mention that changing already implemented modules is risky. By depending on abstraction and not on
a concrete implementation, we can reduce that risk by not having to change high-level modules in our project.

Finally, DIP when applied correctly gives us the flexibility and stability at the level of the entire architecture of our
application. Our application will be able to evolve more securely and become stable and robust.

Conclusion

So to sum up, the Dependency Inversion Principle is the last part of the SOLID principles which introduce an abstraction
between high and low-level components inside our project to remove dependencies between them.

If someone asks: „Should I put an effort to implement the DIP into my code?“, our answer would be: „Yes you should“.
Loosely coupled code and reusable components should be our goal and responsibility when developing software
applications.
SOLID Principles in C# – Dependency Inversion Principle

Posted by Marinko Spasojevic | Updated Date Jan 13, 2022 | 4

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn
how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials
(Security book, Docker book, and other bonus files) are included in the Premium package!

The basic idea behind the Dependency Inversion Principle is that we should create the higher-level modules with its
complex logic in such a way to be reusable and unaffected by any change from the lower-level modules in our application.
To achieve this kind of behavior in our apps, we introduce abstraction which decouples higher from lower-level modules.

Having this idea in mind the Dependency Inversion Principle states that

 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.

We are going to make all of this easier to understand with an example and additional explanations.

To download the source code for this project, check out the Dependency Inversion Principle Project Source Code.

To read about other SOLID principles, check out our SOLID Principles page.

What are the High-Level and Low-Level Modules


The high-level modules describe those operations in our application that have more abstract nature and contain more
complex logic. These modules orchestrate low-level modules in our application.

The low-level modules contain more specific individual components focusing on details and smaller parts of the application.
These modules are used inside the high-level modules in our app.

What we need to understand when talking about DIP and these modules is that both, the high-level and low-level modules,
depend on abstractions. We can find different opinions about if the DIP inverts dependency between high and low-level
modules or not. Some agree with the first opinion and others prefer the second. But the common ground is that the DIP
creates a decoupled structure between high and low-level modules by introducing abstraction between them.

Dependency Injection is one way of implementing the Dependency Inversion Principle.

Example Which Violates DIP

Let’s start by creating two enumerations and one model class:

public enum Gender


{
Male,
Female
}
public enum Position
{
Administrator,
Manager,
Executive
}
public class Employee
{
public string Name { get; set; }
public Gender Gender { get; set; }
public Position Position { get; set; }
}

To continue, we are going to create one low-level class which keeps (in a simplified way) track of our employees:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
}

Furthermore, we are going to create a higher-level class to perform some kind of statistical analysis on our employees:

public class EmployeeStatistics


{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers()
{
//logic goes here
}
}

With this kind of structure in our EmployeeManager class, we can’t make use of the _employess list in the
EmployeeStatistics class, so the obvious solution would be to expose that private list:

public class EmployeeManager


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public List<Employee> Employees => _employees;
}

Now, we can complete the Count method logic:


Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<
public class EmployeeStatistics
{
private readonly EmployeeManager _empManager;
public EmployeeStatistics(EmployeeManager empManager)
{
_empManager = empManager;
}
public int CountFemaleManagers () =>
_empManager.Employees.Count(emp => emp.Gender == Gender.Female && emp.Position == Position.Manager);
}

Even though this will work just fine, this is not what we consider a good code and it violates the DIP.

How is that?

Well, first of all, our EmployeeStatistics class has a strong relation (coupled) to the EmployeeManager class and we
can’t send any other object in the EmployeeStatistics constructor except the EmployeeManager object. The
second problem is that we are using the public property from the low-level class inside the high-level class. By doing so, our
low-level class can’t change its way of keeping track of employees. If we want to change its behavior to use a dictionary
instead of a list, we need to change the EmployeeStatistics class behavior for sure. And that’s something we want to
avoid if possible.

Making Our Code Better by implementing the Dependency Inversion Principle

What we want is to decouple our two classes so the both of them depend on abstraction.

So, the first thing we need to do is to create the IEmployeeSearchable interface:


public interface IEmployeeSearchable
{
IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position);
}

Then, let’s modify the EmployeeManager class:

public class EmployeeManager: IEmployeeSearchable


{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position)
=> _employees.Where(emp => emp.Gender == gender && emp.Position == position);
}

Finally, we can modify the EmployeeStatistics class:

public class EmployeeStatistics


{
private readonly IEmployeeSearchable _emp;
public EmployeeStatistics(IEmployeeSearchable emp)
{
_emp = emp;
}
public int CountFemaleManagers() =>
_emp.GetEmployeesByGenderAndPosition(Gender.Female, Position.Manager).Count();
}

This looks much better now and it’s implemented by DIP rules. Now, our EmployeeStatistics class is not dependent
on the lower-level class and the EmployeeManager class can change its behavior about storing employees as well.

Wanna join Code Maze Team, help us produce more awesome .NET/C# content and get paid? >> JOIN US! <<

Finally, we can check the result by modifying Program.cs class:

class Program
{
static void Main(string[] args)
{
var empManager = new EmployeeManager();
empManager.AddEmployee(new Employee { Name = "Leen", Gender = Gender.Female, Position = Position.Manager });
empManager.AddEmployee(new Employee { Name = "Mike", Gender = Gender.Male, Position = Position.Administrator
});
var stats = new EmployeeStatistics(empManager);
Console.WriteLine($"Number of female managers in our company is: {stats.CountFemaleManagers()}");
}
}
Benefits of Implementing the Dependency Inversion Principle

Reducing the number of dependencies among modules is an important part of the process of creating an application. This is
something that we get if we implement DIP correctly. Our classes are not tightly coupled with the lower-tier objects and we
can easily reuse the logic from the high-tier modules.

So, the main reason why DIP is so important is the modularity and reusability of the application modules.

It is also important to mention that changing already implemented modules is risky. By depending on abstraction and not on
a concrete implementation, we can reduce that risk by not having to change high-level modules in our project.

Finally, DIP when applied correctly gives us the flexibility and stability at the level of the entire architecture of our
application. Our application will be able to evolve more securely and become stable and robust.

Conclusion

So to sum up, the Dependency Inversion Principle is the last part of the SOLID principles which introduce an abstraction
between high and low-level components inside our project to remove dependencies between them.

If someone asks: „Should I put an effort to implement the DIP into my code?“, our answer would be: „Yes you should“.
Loosely coupled code and reusable components should be our goal and responsibility when developing software
applications.

You might also like