Saturday, 19 April 2025

Custom Immutable Class

Creating an immutable class in C# ensures that once an instance is created, its state cannot be modified. This is useful for Creating reliable and thread-safe objects. Here’s how you can achieve this: 

1- Use readonly fields and initialize them through the constructor. 
2- Avoid setters for properties. 
3- Mark the class as sealed to prevent inheritance (optional). Here’s a simple example:
public sealed class ImmutablePerson
{
    public readonly string FirstName { get; }
    public readonly string LastName { get; }

    public ImmutablePerson(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
    public string GetFullName()
    {
      return  $"{FirstName} {LastName}"
    }
}

var person = new ImmutablePerson("John", "Doe");
 Console.WriteLine(person.GetFullName());
In this example: 
1- The FirstName and LastName properties are read-only. 
2- The only way to set FirstName and LastName is through the constructor. 
3- The class is sealed to prevent modification through inheritance.
Share:

Multiple implementations of an interface with number of Services

All ManagerService, TeamLeaderService and EngineerService are registered with the DI container. 
 The EmployeeController constructor injects IEnumerable <ISalaryService >, allowing you to iterate through all registered implementations and call their Execute methods. Alright, so you've got multiple implementations of an interface, and you want to call a specific service based on some criteria. Here’s a more detailed approach to achieve this: Define Your Interface and Implementations:
public interface ISalaryService
{
    void Execute();
}

public class ManagerService : ISalaryService
{
    public float ExecuteSalary() => 10000 + (10000 * .50) ;
}

public class TeamLeaderService : ISalaryService
{
    public float ExecuteSalary() => 10000 + (10000 * .20);
}
public class EngineerService : ISalaryService
{
    public float ExecuteSalary() => 10000 + (10000 * .10);
}
Register Multiple Implementations with Named Options: You can use named registrations in the DI container to differentiate between the services.
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient <ISalaryService, ManagerService>(sp => new ManagerService());
        services.AddTransient<ISalaryService TeamLeaderService>(sp => new TeamLeaderService());
	services.AddTransient<Isalaryservice EngineerService>(sp => new EngineerService());
		
       services.AddTransient<Func<string, ISalaryService>>(serviceProvider => key =>
        {
            return key switch
            {
                "MA" => serviceProvider.GetService(),
                "TL" => serviceProvider.GetService(),
		"SE" => serviceProvider.GetService(),
                _ => throw new KeyNotFoundException()
            };
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Configuration code
    }
}
Resolve Specific Implementation: Use a factory pattern to resolve and call the specific service based on a key.
public class EmployeeController : ControllerBase
{
    private readonly Func<string, ISalaryService> _serviceFactory;

    public EmployeeController(Func<string, ISalaryService> serviceFactory)
    {
        _serviceManager = serviceManager;
    }

    [HttpGet("ExecuteSalaryService")]
    public IActionResult ExecuteSalaryService([FromQuery] string serviceName)
    {
        var service = _serviceManager(serviceName);
        flot salary=service.ExecuteSalary();
	var data=new { totalSal=salary};
        return Ok(data);
    }
}
In this example:All ManagerService, TeamLeaderService and EngineerService are registered with the DI container.  A factory delegate (Func<string, ISalaryService >) is registered to resolve the service based on a key.  EmployeeController injects the factory and uses it to call the specific service based on the serviceName query parameter.
Share:

Monday, 5 August 2024

intview questions

using System;
public class HelloWorld
{
    public static void Main(string[] args)
    {
        A obja=new B();
        obja.Method();
    }
}

public class A{

    static A(){
        Console.WriteLine("construct static A");
    }

    public A(){
         Console.WriteLine("construct default A");
    }

    public void Method(){
         Console.WriteLine("called method of A");
    }
}

public class B : A
{
    static B(){
        Console.WriteLine("construct static B");
    }

    public B(){
         Console.WriteLine("construct default B");
    }

    public void Method(){
         Console.WriteLine("called method of B");
    }
}

 

Output :

construct static B

construct static A

construct default A

construct default B

called method of A
Share: