Monday, October 9, 2023

Dependency injection in C Sharp

The Dependency Injection Design Pattern is the most commonly used design pattern nowadays to remove the dependencies between the objects.

Dependency Injection (DI) is a design pattern used to implement IoC (Inversion of Control.

Dependency Injection is mainly on three classes

  • Service Class
  • Client Class
  • Injector Class
Client Class: The Client Class (dependent class) is a class that depends on the Service Class. That means the Client Class wants to use the Services (Methods) of the Service Class.

Service Class: The service class (dependency) is a class that provides service to the client class.

Injector Class: The Injector Class is a class that injects the Service Class object into the Client Class.

There are various ways to implement C# Dependency Injection:

  1. Constructor Dependency Injection
  2. Property Dependency Injection
  3. Method Dependency Injection

First we will learn what will  happened if we are not using DI .
Example without using Dependency Injection Design Pattern in C#
Create a Console Application

Create a Employee.cs  and add four properties to it

















EmpDal.cs
This is going to service Class. This is the class that is responsible for Interacting with the Database. This class is going to be used by the EmpBal class.






EmpBAL.cs (Client)
This is  going to be Client Class. This is the Class that is going to consume the services provided by the EmpDAL Service Class. That means it is the Dependent Class which is Depending on the EmpDAL Service Class.














As you can see in the above code, in order to get the data, the EmpBal class depends on the EmpDAL class. In the GetEmployeeDetails() method of the EmpBAL class, we create an instance of the EmpDAL This is a tight coupling because the EmpDAL is tightly coupled with the EmpBAL class. Every time the EmpDAL class changes, the EmpBaL class also needs to change. This is the problem. Let us see how to use constructor dependency injection to loosely couple these classes.

Using Constructor Dependency Injection Design Pattern in C#
Let us see, how we can use it in the constructor . To make the classes loosely coupled we will first modify the EmpDal.cs as below. We will create a new interface class file and inherit that in the EmpDal.cs file










As, per the above code Dependency Object should be Interface-Based In our example, the EmpDAL is the Dependency Object as this object is going to be used by the EmpBal class. So we created the IEmployeeDAL interface and then implement that IEmployeeDAL interface in the EmpDAL class.

Now, we will modify the EmpBal.cs class As you can see in the below code, here we created one constructor which accepts one parameter of the Dependency Object type. The point that you need to keep the focus on is, the parameter of the constructor is of the type interface, not the concrete class. Now, this parameter can accept any concrete class object that implements the IEmployeeDAL interface.















So here in the EmpBaL class, we are not creating the object of the EmpDAL class. Instead, we are passing it as a parameter to the constructor of the EmpBAL class. As we are Injecting the Dependency Object through the constructor, it is called Constructor Dependency Injection in C#.

Output












Property Injection in DI
 The Injector needs to Inject the Dependency Object through a public property of the client class.

Let us modify the EmpBal.cs















As you can see in the above code, we are injecting the dependency object through a public property i.e. EmployeeDataObject of the EmpBAL class. As we are setting the dependency object through the setter property, we can call this Setter Dependency Injection in C#. Now, we need to use the property EmployeeDataObject in order to access the instance of IEmployeeDAL.

Program.cs














Method Dependency Injection 
we need to supply the dependency object through a public method of the client class

Example

Modify the EmpBal.cs








Program.cs







Output






Dependency Inversion Principle

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes


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

The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.

When one class is aware of  the design and implementation of another class, it increases the risk that , any changes made  to one class will disrupt  the other class. Therefore, it is important to maintain loose coupling between high-level and low-level modules/classes. To achieve this, both classes should depend on abstractions rather than having direct knowledge of each other. If this concept is currently unclear do not worry. By the end of this article, you will have a clear understanding of this concept through examples.

First, we will see an example without following the Dependency Inversion Principle. Then, we will identify the problems of not following the Dependency Inversion Principle. Finally, we will rewrite the same example using the Dependency Inversion Principle so that you can easily understand this concept

Create a Console Application and then add the following class files.









EmpDal.cs









DataAccessFactory.cs









EmpBal.cs








The following class has one constructor used to create an instance of the EmployeeDataAccessLogic class. Here, within the constructor, we call the static GetEmployeeDataAccessObj() method on the DataAccessFactory class, which will return an instance of EmployeeDataAccessLogic.


We then initialize the _EmployeeDataAccessLogic property with the returned instance. Additionally, we have one method, GetEmployeeDetails, which calls the GetEmployeeDetails method on the EmpDal instance to retrieve the employee details by employee ID.


So now, as per Dependency Inversion Principle

According to the definition of the Dependency Inversion Principle  High-Level module should not depend on Low-level modules. Both should depend on the abstraction.

From the above example, we need to identify High-Level Module (class) and the Low-Level Module (class) in our example. 

A High-Level Module is a module that always depends on other modules. So, in our example, the EmpBal class depends on the EmpDal class, so here, the EmpBal class is the high-level module, and the EmpDal class is the low-level module.

So, according to the first rule of the Dependency Inversion Principle in C#, the EmpBal class/module should not depend on the concrete EmpDal class/module. Instead, both classes should depend on an abstraction. However, in our example, the way we have implemented the code, the EmpBal depending on the EmpDal class, means that we are not following the first rule. In the later part of this article, I will modify the example to follow the Dependency Inversion Principle.

The second rule of the Dependency Inversion Principle states that Abstractions"  should not depend on details. Details should depend on "abstractions" 

Let us understand about abstraction Now

In the previous example the EmpBal and EmpDal are concrete classes, meaning we can create objects of them. That is means we are also not following the second rule of the Dependency Inversion Principle.

As per the Dependency Inversion Principle in C#, the EmpBal (High-Level Module) should not depend on the concrete EmpDal (Low-Level Module) class. Both classes should depend on Abstractions, meaning both classes should depend on an Interface or an Abstract Class.

Now, the question is what methods should be in interface or abstract class.

Now, let us create an interface to achieve this principle













Now, we need to implement the above interface in EmpDal as shown below.
















Now, 
we need to change the DataAccessFactory class. Here, we need to change the return type of the GetEmployeeDataAccessObj to IEmployeeDataAccessLogic as shown below








Now, we will change the EmpBal class code as shown below









That’s it. We have implemented the Dependency Inversion Principle in our example using C# language where the High-Level module (EmpBal) and Low-Level module (EmpDal) depend on abstraction (IEmployeeDataAccess). Also, abstraction (IEmployeeDataAccess) does not depend on details (EmpDal), but details depend on abstraction.








Now run the program.

Output












Solid Priciples

SOLID principles allows object oriented programming implementation in an efficient better way into project development

     S-->Single Responsibility Principle  [SRP]

     O-->Open Closed Principle           [OCP]

     L-->Liskov Substitution Principle   [LSP]

     I-->Interface Segregation Principle [ISP]

     D-->Dependency Inversion Principle  [DIP]

S-Single Responsibility Principle

This means that every class or similar structure in your code should have only one job.

The class should be provided with single responsibility related to a particular task.

A module or class should have a very small piece of responsibility  in the entire application, This also reduces number of bugs and  improves development speed and most importantly makes developer’s  life lot easier

Example










It looks fine, but it is not following SRP. 

The SendEmailTo and ValidateEmailAddres methods have nothing to do with the UserService class. Let's refract it.

Let's refract it to satisfy SRP












O: Open/Closed Principle

Software entities (classes, modules) should be opened for extension, but closed for modification.

This principle suggests that the class should be easily extended but there is no need to change its core implementations.

Now, the below code violates OCP principle if the bank introduces a new Account  type. the code to be modified for adding a new account type.



      







We can apply OCP by using interface (or) abstract class when you want to      extend functionality will create a new class to each type of acct type customer 

   











Note:

when we need corporate acct type, we can create a new class by extending        interface without modifying exiting class[no modification] but extension

  







In the above code three new classes are created; Regularsavingaccount,  SalarySavingAccount, and CorporateAccount, by extending them from IAccount.

This solves the problem of modification of class and by extending interface,  we can extend functionality.

Above code is implementing both OCP and SRP principle, as each class has  single is doing a single task and we are not modifying class and only doing  an extension.

In C#, Open/Closed principle can be applied using the following approaches:

Using Function Parameters

Using Extension methods

Using Classes, Abstract class, or Interface-based Inheritance

Generics

By using Interface











Now, some developers want to change the Method DebugDetails, So to satisfy there needs you need to modify the Logger class and either create a new method for them or modify the existing DebugDetails() method. If you change the existing DebugDetails() method then the other developers who don't want this change will also be affected.

To solve this problem is to use class based-inheritance (polymorphism) 









Now, a new class can inherit the Logger class and change one or more method behavior











Liskov Substitution Principle[LSP]


Base classes must be able to use objects of derived classes without knowing it. LSP states that the child class should be perfectly substitutable for their parent class.

Base class var should be able to reference derived class object, it is called Upcasting principle

When you derived a class from a base class then the derived class should correctly implement all the methods of the base class. It should not remove some methods by throwing NotImplementedException.

LSP says that the derived class should correctly implement the base class methods.











To correct above implementation, we need to refactor this code by introducing interface with method called GetShape.

 


namespace Demo
{
 class Program
 {
 static void Main(string[] args)
 {
 Shape shape = new Circle();
 Console.WriteLine(shape.GetShape());
 shape = new Triangle ();
 Console.WriteLine(shape.GetShape());
 }
 }
 
 public abstract class Shape
 {
 public abstract string GetShape();
 }
 
 public class Triangle: Shape
 {
 public override string GetShape()
 {
 return "Triangle";
 }
 }
 
 public class Circle: Triangle
 {
 public override string GetShape()
 {
 return "Circle";
 }
 }
}









Output

Circle

Triangle


I-->Interface Segration Principle[ISP]

class should not be forced to implement methods which it does not need, and the contracts should be broken down to thin ones

[break one interface into different interfaces].

Using ISP, we can create separate interfaces for each operation or            requirement rather than having a single interface with so many methods.

Example








We can resolve this violation by dividing IOrder Interface.












D-->Dependency Inversion Principle  [DIP]

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes


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

The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.

Refer Next Article of Mine to know more about Dependency Injection.





Tuesday, October 3, 2023

Different Types of Loops in Typescript(For, While)

for Loop

The for loop is used to execute a block of code a given number of times, which is specified by a condition.

Example

for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }

Output
Serial Number0 Serial Number1 Serial Number2

for...of Loop:

This will be used with arrays,lists,tuples

Example
for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }
  let arr = [10, 20, 30, 40];

  for (var val of arr) {
    console.log(val);
  }

Output

Serial Number0 Serial Number1 Serial Number2 10 20 30 40


for...in Loop

This can be used with an array, list, or tuple. The for...in loop iterates through a list or collection and returns an index on each iteration.

for (let i = 0; i < 3; i++) {
    console.log ("Serial Number" + i);
  }
  let arr = [10, 20, 30, 40];

  for (var val of arr) {
    console.log(val);
  }
  for (var index in arr) {
    console.log(index);
 
    console.log(arr[index]);
  }

Output

10 20 30 40 0 10 1 20 2 30 3 40

While Loop
The loop runs until the condition value is met.

Example

let i: number = 2;

while (i < 4) {
    console.log( "Serial Number." + i )
    i++;
}

Output
Serial Number.2 Serial Number.3


do..while loop

The do..while loop is similar to the while loop, except that the condition is given at the end of the loop. The do..while loop runs the block of code at least once before checking for the specified condition. For the rest of the iterations, it runs the block of code only if the specified condition is met.

Example

Syntax:

do {
// code block to be executed
}
while (condition expression);

   
let i: number = 2;
do {
    console.log("Serial Number." + i )
    i++;
} while ( i < 4)


Output
Serial Number.2 Serial Number.3

Kubernetes

Prerequisites We assume anyone who wants to understand Kubernetes should have an understating of how the Docker works, how the Docker images...