Saturday, May 09, 2020

APS.Net Core Dependency Injection





ASP.Net Core has a built-in dependency framework. This means you don't need to write your own plumbing code to achieve Dependency Injection. ASP.Net Core helps enforces the Dependency Injection Principle out of the box.   


What is a dependency?


Dependency is established between classes when one class needs another class to fulfil its functionality. Below are two classes class A and class B. Class A needs class B to accomplish the addition functionality. So class A has a dependency on class B or class A is dependent on class B.

class A{

    public int addition(int x, int y)
    {
        B objB = new B();
        return objB(x,y);
    }
}

While this is a perfectly viable situation to do, it makes class A very tightly coupled with class B. To further elaborate on this, imagine you discovered a faster algorithm in class C. You would now have to rewrite class A, remove the dependency on B and use C instead. While this doesn't seem difficult to do in their example it may not be the same if this dependency has been used in several places throughout your code. 


Dependency injection


Is there a better way to manage a dependency? Yes there is and its called Dependency Injection. Instead of letting class A manage the creation of class B, we delegate this responsibility to the class calling class A and then injecting that object into class A when required.  


class A{

    private B _objB;

    public A(B objB)
    {
        _objB = objB;
    }

    public int addition(int x, int y)
    {
        return _objB(x,y);
    }
}


class Program{

     public static void main(string args[])
     {
          B objB = new B();
          A objA = new A(objB);
          Console.WriteLine(obja.addition(4,5).ToString());
     }
}

Dependency injection in ASP.Core


ASP.Core has introduced a dependency injection container in the form of a ConfigureServices method in the Startup classLet's walk this through by creating and registering a service called MyService.



Step1: Create an interface for our service called IMyService.

interface IMyService{
     public void GetMyUsers();
}

Step2: Create a service called MyService that implements interface IMyService.

public class MyService: IMyService{
   
     public void GetMyUsers(){
         //****Do something here *****
     }
}

Step3: Next we register MyService in the ConfigureServices method of the Startup class. We do this by using one of the three methods services.AddTransient, services.AddScoped and services.AddSingleton provided by IServiceCollection. For more information on these methods and the lifetime of the registered services see Service lifetimes below.


public class Startup{


    public IConfiguration Configuration { get; }



    public Startup(IConfiguration configuration)

    {

        Configuration = configuration;
    }


    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IMyServiceMyService>();      
    }
}


Step4: In your controller class you can inject MyService in the constructor and use it like below. 


 public class MyController : ControllerBase{

        private IMyService _myService;  

        public MyController(MyService _myService)
        {
            _myService = myService;
        }


        [HttpGet]
        [Route("/api/user")]
        public IActionResult Get()
        {
            _myService.GetMyUsers();
        }
 }

Using Service Extensions


You can call write your own service extensions services.Add{SERVICE_NAME} by extending the ServicesConfiguration class like below.



public static class ServicesConfiguration{


        public static void AddMyService(this IServiceCollection     services)

        {

            services.AddScoped<IMyServiceMyService>();      

        }

}


You can then use it in the Startup class like below.


public class Startup{


    public IConfiguration Configuration { get; }



    public Startup(IConfiguration configuration)

    {

        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IMyServiceMyService>();      
    }
}


Service lifetimes


Transient

This is probably the default choice, its best suited for lightweight and stateless services. You can use this method in applications that don't implement a request-response pattern.

Scoped

This is best suited for web applications as it is created once per client request.


Singleton

This is created once for the life of the application. There is only one instance of this service. 



Tuesday, May 05, 2020

Part 2 : Using Jenkins to build .Net Core and NUnit



Run NUnit tests from Jenkins



This blog walks you through setting Jenkins up for hooking Nunit tests. 


Enable the MSTest plugin


In this step, you will learn how to install the MSTest plugin.
  • Once on the main page of Jenkin's you will need to navigate to Manage Jenkins in the left-hand navigation.
  • Then click on Manage Plugins like below.
  • Once on the main page of Jenkin's you will need to navigate to Manage Jenkins in the left-hand navigation.
  • Then click on Manage Plugins like below.
  • Then click on the Available tab.
  • Check the MSTest checkbox under .NET Development.
  • Scroll down and click on "Download now and install after restart".


Adding NUnit to project configuration



  • In your project go to Configure > Build 
  • Add a build step
  • In the dropdown scroll down to Execute Windows Batch Command
  • Ensure this step is placed after your MSBuild step
  • Add the following, replacing the variables with exact path to the files. 

dotnet test [fullpath]\NUnitTestApplication.dll --logger "trx;LogFileName=TestResults.trx"




Adding Post Build Test results 


  • In your project go to Configure.  
  • Add post-build action > Publish MSTest test result report. 
  • You can leave everything else as is like below.




Report 



You should now be able to see the results of your test like below 







Monday, May 04, 2020

The startegy pattern




The Strategy pattern defines a family of algorithms whose individual behaviours are encapsulated allowing them to be interchangeable. Strategy lets the algorithm vary independently from clients that use it. You can use this pattern to implement the Open/Close principle. 



Problem 


I'm building a digital wallet, users can choose the kind of encryption they need to protect their data with. Since the process of encrypting is the same. That is choosing their data, performing the encryption and storing it, we do not wish to duplicate the process for each new encryption type. Also, we want the flexibility to create new encryptions in the future and not affect the existing encrypted data. The Strategy Pattern can do just this.   

Analysis 


We need to be able to encapsulate the encryption algorithms and switch between them at runtime. Without the client being aware of the algorithms themselves. 

Solution 


First, we define an encryption interface IEncryption. We can now create different algorithms as the implementation of this interface. We now have three encryption classes class SHA1, class SHA256 and class SHA512 that implement the IEncryption interface. Then we create an Encryption Service class called EncryptionService that maintains the reference to the algorithms and decouples the client form the actual encryption classes. Alternatively, we could have substituted the interface with an Abstract class, this would allow us to define a default encryption to use.


Illustration 







Code


  public class Program
    {
        private static void Main(string[] args)
        {
            List encsvc = new List { new EncryptionService(new SHA1()), new EncryptionService(new SHA256()), new EncryptionService(new SHA512()) };

            foreach (var con in encsvc)
            {
                con.DoEncryption();
            }

            Console.ReadKey();
        }
    }


    public interface IEncryption

    {
        public void Encrypt();
    }


    public class SHA1 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA1");
        }
    }

    internal class SHA256 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA256");
        }
    }

    internal class SHA512 : IEncryption

    {
        public void Encrypt()
        {
            Console.WriteLine(
              "Encrypt using SHA512");
        }
    }

    internal class EncryptionService

    {
        private IEncryption encryption;


        public EncryptionService(IEncryption encryption)
        {
            this.encryption = encryption;
        }

        public void DoEncryption()
        {
            encryption.Encrypt();
        }
    }
}