.Net, Azure, C#, Cloud Design Patterns, Nutshell Series, Technology and tricks

SOLID Principles (with c# examples) – Nutshell

SOLID Principles in .NET – Explained with Examples

SOLID Principles in .NET – Explained with Examples

The SOLID principles are five guidelines that help developers write clean, maintainable, and extensible object-oriented code.
Below we go through each principle with concise C# examples showing what is bad and what is good.


1. Single Responsibility Principle (SRP)

Rule: A class should have only one reason to change.

Bad Example

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }

    public void SendEmail(string message)
    {
        // Logic to send email
    }
}

Here, User manages both data and email-sending logic. It has more than one responsibility.

Good Example

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class EmailService
{
    public void SendEmail(string email, string message)
    {
        // Logic to send email
    }
}

User now manages only user data, while EmailService handles emails. Each has one responsibility.


2. Open/Closed Principle (OCP)

Rule: Classes should be open for extension but closed for modification.

Bad Example

public class AreaCalculator
{
    public double CalculateArea(object shape)
    {
        if (shape is Circle c)
            return Math.PI * c.Radius * c.Radius;
        if (shape is Square s)
            return s.Side * s.Side;
        return 0;
    }
}

Adding a new shape forces us to modify AreaCalculator, violating OCP.

Good Example

public abstract class Shape
{
    public abstract double Area();
}

public class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area() => Math.PI * Radius * Radius;
}

public class Square : Shape
{
    public double Side { get; set; }
    public override double Area() => Side * Side;
}

Each shape implements its own Area. Adding new shapes doesn’t require changing existing code.


3. Liskov Substitution Principle (LSP)

Rule: Derived classes should be substitutable for their base types without breaking behavior.

Bad Example

public class Bird
{
    public virtual void Fly() { }
}

public class Ostrich : Bird
{
    public override void Fly()
    {
        throw new NotImplementedException();
    }
}

Substituting Ostrich for Bird breaks behavior, since ostriches cannot fly.

Good Example

public abstract class Shape
{
    public abstract double Area();
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public override double Area() => Width * Height;
}

Rectangle correctly substitutes Shape and can be used anywhere Shape is expected.


4. Interface Segregation Principle (ISP)

Rule: Don’t force classes to implement methods they don’t use.

Bad Example

public interface IMachine
{
    void Print();
    void Scan();
}

public class SimplePrinter : IMachine
{
    public void Print() { }
    public void Scan() { throw new NotImplementedException(); }
}

SimplePrinter doesn’t support scanning, yet it is forced to implement it.

Good Example

public interface IPrinter
{
    void Print();
}

public interface IScanner
{
    void Scan();
}

public class MultiFunctionPrinter : IPrinter, IScanner
{
    public void Print()
    {
        Console.WriteLine("Printing document...");
    }

    public void Scan()
    {
        Console.WriteLine("Scanning document...");
    }
}

Now classes only implement what they need. A simple printer just implements IPrinter.


5. Dependency Inversion Principle (DIP)

Rule: High-level modules should not depend on low-level modules. Both should depend on abstractions.

Bad Example

public class DataManager
{
    private readonly SQLDatabase _db = new SQLDatabase();

    public void Save(string data)
    {
        _db.SaveData(data);
    }
}

public class SQLDatabase
{
    public void SaveData(string data) { }
}

DataManager is tightly coupled to SQLDatabase, making it hard to switch databases.

Good Example

public interface IDatabase
{
    void SaveData(string data);
}

public class SQLDatabase : IDatabase
{
    public void SaveData(string data)
    {
        // Save data to SQL database
    }
}

public class DataManager
{
    private readonly IDatabase _database;
    public DataManager(IDatabase database)
    {
        _database = database;
    }

    public void Save(string data)
    {
        _database.SaveData(data);
    }
}

DataManager now depends on IDatabase. Any database implementation can be injected.


Key Takeaways

  • SRP — One class, one responsibility.
  • OCP — Extend, don’t modify working code.
  • LSP — Subtypes must preserve base-class behavior.
  • ISP — Keep interfaces small and focused.
  • DIP — Depend on abstractions, not concretions.
.Net, C#

Creating String extension function

public static string ToCamelCase(this string str)
{
if (!string.IsNullOrEmpty(str) && str.Length > 1)
{
return Char.ToUpperInvariant(str[0]) + str.Substring(1);
}
return str;
}

Usage:
string text = “test data”;
string camalCaseText = text.ToCamelCase();

Output: Test data

Function declaration should be done outside of main class.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/how-to-add-custom-methods-for-linq-queries

BizTalk, C#

Static variables are non serlizable by default – A Common problem in BizTalk solutions

Below error appears on restart of host instance manually or due to the automatic restart of host instance due to DTC issue (Also know as Host instance recovering its state due to network issues or crashing of instances)

Shape name: ShapeName
ShapeId: d0e0ca4a-cd4b-44d2-a662-526f65665ad5
Exception thrown from: segment 1, progress 37
Inner exception: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

OR

Object reference not set an instance of an object.

Problem: Static variable are not serlizable. This is the standard problem in BizTalk solution where static variables are used within class libraries..

Solution:

With Serialization, we can only serialize properties that are:

  • Public
  • Not static
  • Not read Only

In this case, if you want to serialize by adding new variable “no1_Serialize“, you must wrap it, like this:

[Serializable]
public class Numbers
{
    public int no;
    public static int no1;
    public SubNumbers SubNumber;

    public int no1_Serialize {get {return no1;} set {no1 = value;} }
}

Ref: https://stackoverflow.com/questions/17222900/serialize-object-along-with-static-member-variables-to-xml


		
.Net, C#, Technology and tricks

System.Runtime.InteropServices.COMException – Task scheduler – Console application

Description: The process was terminated due to an unhandled exception.
Exception Info: System.Runtime.InteropServices.COMException
Stack:
at Microsoft.Office.Interop.Excel.Workbooks.Open(System.String, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object)
at NotificationReportGenerator.ExcelFactory.ReadExcel(System.String)
at NotificationReportGenerator.Program.Main(System.String[])

The solution for this appalling BUG in Microsoft IIS & Excel is terrific:

  1. Create directory “C:\Windows\SysWOW64\config\systemprofile\Desktop ” (for 64 bit Windows) or “C:\Windows\System32\config\systemprofile\Desktop ” (for 32 bit Windows)
  2. Set Full control permissions for directory Desktop (for example in Win7 & IIS 7 & DefaultAppPool set permissions for user
    “IIS AppPool\DefaultAppPool”)
.Net, C#, Visual Studio

Issue with Visual Studio sign using Azure account

If you are ending with errors while logging in to Visual Studio (2015 or 2017) with your Microsoft subscription account with error message “Cookies are blocked, cannot login”. Then below is setting change you need to do in “Internet Options” to resolve it.

Visual studio always used internet engine for internet connectivity and I didn’t find any way to change it to use to Mozilla or any other internet engine.

Below  change in “Internet Options” setting prompts to accept cookies and this resolved the issue.

Untitled.png

After changing, try to login, you we will prompted to accept cookie couple of times. This will resolve the issue