The Dependency Inversion Principle (DIP)

Dependency Inversion Principle in c#

The Dependency Inversion Principle states that:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces).
  2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

Source: Wikipedia

Other SOLID Principles

Example without DIP

public class UserRepository
{
    public string GetUserById(int id)
    {
        // Code to fetch user from the database
        return "User";
    }
}

public class UserService
{
    private readonly UserRepository _userRepository;

    public UserService()
    {
        _userRepository = new UserRepository();
    }
    public string GetUser(int id)
    {
        return _userRepository.GetUserById(id);
    }
}

One problem with this code is , theUserService is tightly coupled with the UserRepository. Another problem is, if you want to use different implementation of UserReposoitory, you can not easily do it. For instance you want to swap your UserRepsoitory to UserRepositoryWithDifferentDatabase.

[Read More]

The Interface Segregation Principle (ISP)

what is Interface Segregation Principle?

📢 Clients should not be forced to depend on interfaces they do not use.

In simpler terms, this principle suggests that an interface should not include methods that implementing classes don’t need. It Encourages us to create smaller interfaces over the big fat interface.

Other SOLID principles

Violating example

Imagine you have an interface for workers in a company:

[Read More]

The Liskov Substitution Principle (LSP)

What is Liskov substitution principle

The Liskov Substitution Principle states that a derived type should be completely replaceable for its base type.

In simpler terms, a child class should do at least what the parent class can do. The child class can have additional behaviors, but it must have all the behaviors that the parent class has.

For instance, an Animal has behaviors (eat, sleep, makeSound). A Dog, which is a subtype of Animal, must have all the behaviors (eat, sleep, makeSound).

[Read More]

Open Closed Principle (OCP)

open closed principle in c#

The Open-Closed Principle is one of the five SOLID principles. It states that a class should be open for extension but closed for modification. In other words, you should be able to add new functionality without changing existing code.

Once you have written your class, it should not be modified in the future. However, this doesn’t mean you cannot modify your class during early development stages. It means that once your application or software is in production and you want to introduce the new functionality, you should extend that class rather than modifying it.

[Read More]

Single Responsibility Principle (SRP)

Single Responsibility Principle in c#

The Single Responsibility Principle (SRP) is a cornerstone of object-oriented design, closely associated with the SOLID principles. It emphasizes that a class should have only one reason to change, meaning it should have a single responsibility or purpose.

What is SRP?

The principle asserts that a class should do only one thing and do it very well. This doesn’t imply that a class should have only one method or behavior, but rather that it should contain a cohesive set of behaviors related to a single responsibility.

[Read More]

Image Upload CRUD Operations in .NET Core WebAPIs

how to upload images in .net core web api

Upload images in .net core apis

In this article, we will learn how to upload/update/delete/read images in .net core APIs. I hate to give long and unnecessary intros, So let’s come to the point’s.

💻 You can get the code from this github repo.

What is the logic behind it? 🤔

When you upload the image (or any file), we will generate the unique image name with it’s extension (eg. uniquename.png). Save the image name in the database and save the file with the same name inside the project. In production apps, you can not simply upload files to the server, you have to give permission to that folder. Or you can use other file storage service, where you will save your files.

[Read More]

Separating the DI Setup From Program.cs file

Separating the DI Setup From Program.cs file

Let’s take a look at the program.cs file below.

using InventoryMgt.Api.Middlewares;
using InventoryMgt.Data.Repositories;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddTransient<ICategoryRepository, CategoryRepository>();
builder.Services.AddTransient<IProductRepository, ProductRepository>();
builder.Services.AddTransient<IPurchaseRepository, PurchaseRepository>();
builder.Services.AddTransient<IStockRepository, StockRepository>();
builder.Services.AddTransient<ISaleRepository, SaleRepository>();
builder.Services.AddTransient<ExceptionMiddleware>();
builder.Services.AddCors(options =>
{
 options.AddDefaultPolicy(policy =>
 {
 policy.WithOrigins("*").AllowAnyHeader().AllowAnyMethod().WithExposedHeaders("X-Pagination");
 });
});
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
 app.UseSwagger();
 app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors();
app.UseAuthorization();
app.ConfigureExceptionMiddleware();
app.MapControllers();

app.Run();

It is a regular program.cs file. Since we use the dependency injection in our application, we have to register lots of service in our program.cs file. For example:

[Read More]

Private Constructor in C#

private constructor in c#

In C#, a private constructor is a constructor method declared with the private access modifier (or without mentioning any modifier). If a class have only a private constructor and does not have any public constructor, then you are not able to create the instance of a class. Example 👇

public class Student
{
 Student() { } // private constructor
}

public class Program
{
 static void Main()
 {
 Student stu = new(); //Error CS0122 'Student.Student()'
 // is inaccessible due to its protection level

    }

}

When you try to create the instance of stu, you will the following error.

[Read More]

Generic Delegates (Action, Func & Predicates) in C#

Generic delegate c#, action func predicate in c#

In C#, delegates are used to refer to methods with a specific signature. Generic delegates extend this concept by allowing you to create delegates that can work with any method signature, rather than being tied to a specific signature.

Here’s a basic example of a generic delegate:

delegate T MyGenericDelegate<T>(T arg);

You can use this generic delegate as follows.

MyGenericDelegate<int> handler1 = CustomSquare;
int square=handler1(4);
Console.WriteLine(square); //16

MyGenericDelegate<string\> handler2 = CustomToUpper;
Console.WriteLine(CustomToUpper("helLo")); //HELLO

In-built Generic delegates

C# comes with inbuilt generic delegates like Action, Func and Predicate.

[Read More]

Delegates, Anonymous Method and Lambda Expression

Delegates, anonymous method and lambda expression in c#

  • Delegates in C# are essentially type-safe function pointers.
  • They allow you to treat methods as objects, enabling you to pass methods as parameters, store them in variables, and invoke them dynamically.
  • Delegates are particularly useful for implementing callback mechanisms and event handling in C#.

delegate void MyDelegate(string message);

You can point this delegate to any method with similar signature.

namespace BasicsOfCSharp;

// Declare a delegate type
delegate void MyDelegate(string message);

class Program
{
 // Method that matches the delegate signature
 static void DisplayMessage(string message)
 {
 Console.WriteLine("Message: " + message);
 }
 static void Main()
 {
        // Instantiate the delegate.
        MyDelegate handler = DisplayMessage;

        // calling the handler
        handler("Hello..");

    }

}

👉Multicast Delegate:

[Read More]