HI WELCOME TO Sirees
Showing posts with label asp.net core. Show all posts
Showing posts with label asp.net core. Show all posts

Dependency Injection

Leave a Comment
In the previous chapter of DIP, we created and used abstraction to make the classes loosely coupled. Here, we are going to implement Dependency Injection and strategy pattern together to move the dependency object creation completely out of the class. This is our third step in making the classes completely loose coupled.

Dependency Injection (DI) is a design pattern used to implement IoC where it allows creation of dependent objects outside of a class and provides those objects to a class through different ways. Using DI, we move the creation and binding of the dependent objects outside of the class that depends on it.
Dependency Injection pattern involves 3 types of classes.
  1. Client Class: The client class (dependent class) is a class which depends on the service class
  2. Service Class: The service class (dependency) is a class that provides service to the client class.
  3. Injector Class: The injector class injects service class object into the client class.
The following figure illustrates the relationship between these classes:

Dependency Injection
As you can see, injector class creates an object of service class, and injects that object to a client object. This way DI pattern separates the responsibility of creating an object of service class out of client class.

Types of Dependency Injection

As you have learned above, the injector class injects the service (dependency) to the client (dependent). The injector class injects dependencies broadly in three ways: through constructor, through property, or through method.
Constructor Injection: In the constructor injection, injector supplies service (dependency) through the client class constructor.
Property Injection: In property injection (aka Setter Injection), injector supplies dependency through a public property of the client class.
Method Injection: In this type of injection, client class implements an interface which declares method(s) to supply dependency and the injector uses this interface to supply dependency to the client class.
Let's take an example from the previous chapter to maintain the continuity. In the previous section of DIP, we used Factory class inside CustomerBusinessLogic class to get an object of CustomerDataAccess object as shown below.
public interface ICustomerDataAccess
{
    string GetCustomerName(int id);
}

public class CustomerDataAccess: ICustomerDataAccess
{
    public CustomerDataAccess() {
    }

    public string GetCustomerName(int id) {
        return "Dummy Customer Name";        
    }
}

public class DataAccessFactory
{
    public static ICustomerDataAccess GetCustomerDataAccessObj() 
    {
        return new CustomerDataAccess();
    }
}

public class CustomerBusinessLogic
{
    ICustomerDataAccess _custDataAccess;

    public CustomerBusinessLogic()
    {
        _custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
    }

    public string GetCustomerName(int id)
    {
        return _custDataAccess.GetCustomerName(id);
    }
}
The problem with the above example is that we used DataAccessFactory inside CustomerBusinessLogic class. So, suppose there is another implementation of ICustomerDataAccessfor some reason and we want to use that new class inside CustomerBusinessLogic. Then, we need to change the source code of CustomerBusinessLogic class also. Dependency injection pattern solves this problem by injecting dependent objects via constructor, property, or interface.
The following figure illustrates the DI pattern implementation for the above example.
Dependency Injection
As you see, CustomerService class becomes injector class which sets an object of service class (CustomerDataAccess) to the client class (CustomerBusinessLogic) either through constructor, property, or method to achieve loose coupling. Let's explore each of these options.

Constructor Injection

As mentioned before, when we provide dependency through the constructor then it's constructor injection.
Consider the following example where we have implemented DI using constructor.
Example: Constructor Injection
public class CustomerBusinessLogic
{
    ICustomerDataAccess _dataAccess;

    public CustomerBusinessLogic(ICustomerDataAccess custDataAccess)
    {
        _dataAccess = custDataAccess;
    }

    public CustomerBusinessLogic()
    {
        _dataAccess = new CustomerDataAccess();
    }

    public string ProcessCustomerData(int id)
    {
        return _dataAccess.GetCustomerName(id);
    }
}

public interface ICustomerDataAccess
{
    string GetCustomerData(int id);
}

public class CustomerDataAccess: ICustomerDataAccess
{
    public CustomerDataAccess()
    {
    }

    public string GetCustomerName(int id) 
    {
        //get the customer name from the db in real application        
        return "Dummy Customer Name"; 
    }
}
In the above example, CustomerBusinessLogic includes constructor with one parameter of type ICustomerDataAccess. Now, the calling class must inject an object of ICustomerDataAccess.
Example: Inject Dependency
public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}
As you can see in the above example, CustomerService class creates and injects CustomerDataAccess object into CustomerBusinessLogic class. Thus, CustomerBusinessLogic class need not create an object of CustomerDataAccess using new keyword or using factory class. The calling class (CustomerService) creates and sets appropriate DataAccess class to the CustomerBusinessLogic class. This way CustomerBusinessLogic and CustomerDataAccess class become more loosely coupled classes.

Property Injection

In the property injection, dependency is provided through public property. Consider the following example.
Example: Property Injection
public class CustomerBusinessLogic
{
    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        return DataAccess.GetCustomerName(id);
    }

    public ICustomerDataAccess DataAccess { get; set; }
}

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic();
        _customerBL.DataAccess = new CustomerDataAccess();
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}
As you can see above, the CustomerBusinessLogic class includes public property named DataAccesswhere you set an instance of a class that has implanted ICustomerDataAccess. So, CustomerServiceclass creates and sets CustomerDataAccess class using this public property.

Method Injection

In the method injection, dependencies are provided through methods. This method can be a class method or interface method.
The following example demonstrates method injection using interface based method.
Example: Interface Injection
interface IDataAccessDependency
{
    void SetDependency(ICustomerDataAccess customerDataAccess);
}

public class CustomerBusinessLogic : IDataAccessDependency
{
    ICustomerDataAccess _dataAccess;

    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        return _dataAccess.GetCustomerName(id);
    }
        
    public void SetDependency(ICustomerDataAccess customerDataAccess)
    {
        _dataAccess = customerDataAccess;
    }
}

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic();
        ((IDataAccessDependency)_customerBL).SetDependency(new CustomerDataAccess());
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}
In the above example, CustomerBusinessLogic class implements IDataAccessDependency interface which includes method SetDependency. So the injector class (CustomerService) will now use this method to inject dependent class (CustomerDataAccess) to the client class.
Thus, you can use DI and strategy pattern to create loose coupled classes.
So far, we have used couple of principles and patterns to achieve loosely coupled classes. In professional projects, there would be many dependent classes and implementing these patterns would be time consuming. Here IoC Container (aka DI container) helps us. Learn about IoC Container in the next chapter.

ASP.NET Core - Dependency Injection

Leave a Comment
ASP.NET Core is designed from scratch to support Dependency Injection. ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container.

Built-in IoC Container

ASP.NET Core framework contains simple out-of-the-box IoC container which does not have as many features as other third party IoC containers. If you want more features such as auto-registration, scanning, interceptors, or decorators then you may replace built-in IoC container with a third party container.
The built-in container is represented by IServiceProvider implementation that supports constructor injection by default. The types (classes) managed by built-in IoC container is called services.
There are basically two types of services in ASP.NET Core:
  1. Framework Services: Services which are a part of ASP.NET Core framework such as IApplicationBuilder, IHostingEnvironment, ILoggerFactory etc.
  2. Application Services: The services (custom types or classes) which you as a programmer create for your application.
In order to let the IoC container automatically inject our application services, we first need to register them with IoC container.

Registering Application Service

Consider the following example of simple ILog interface and its implementation class. We will see how to register it with built-in IoC container and use it in our application.
public interface ILog
{
    void info(string str);
}

class MyConsoleLogger : ILog
{
    public void info(string str)
    {
        Console.WriteLine(str);
    }
}
ASP.NET Core allows us to register our application services with IoC container, in the ConfigureServices method of the Startup class. The ConfigureServices method includes a parameter of IServiceCollection type which is used to register application services.
Let's register above ILog with IoC container in ConfigureServices() method as shown below.
Example: Register Service
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));        
    }

    // other code removed for clarity.. 
}
As you can see above, Add() method of IServiceCollection instance is used to register a service with an IoC container. The ServiceDescriptor is used to specify a service type and its instance. We have specified ILog as service type and MyConsoleLogger as its instance. This will register ILogservice as a singleton by default. Now, an IoC container will create a singleton object of MyConsoleLogger class and inject it in the constructor of classes wherever we include ILog as a constructor or method parameter throughout the application.
Thus, we can register our custom application services with an IoC container in ASP.NET Core application. There are other extension methods available for quick and easy registration of services which we will see later in this chapter.

Understanding Service Lifetime

Built-in IoC container manages the lifetime of a registered service type. It automatically disposes a service instance based on the specified lifetime.
The built-in IoC container supports three kinds of lifetimes:
  1. Singleton: IoC container will create and share a single instance of a service throughout the application's lifetime.
  2. Transient: The IoC container will create a new instance of the specified service type every time you ask for it.
  3. Scoped: IoC container will create an instance of the specified service type once per request and will be shared in a single request.
The following example shows how to register a service with different lifetimes.
Example: Register a Service with Lifetime
public void ConfigureServices(IServiceCollection services)
{
    services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));    // singleton
    
    services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Transient)); // Transient
    
    services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Scoped));    // Scoped
}

Extension Methods for Registration

ASP.NET Core framework includes extension methods for each types of lifetime; AddSingleton()AddTransient() and AddScoped() methods for singleton, transient and scoped lifetime respectively.
The following example shows the ways of registering types (service) using extension methods.
Example: Extension Methods
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ILog, MyConsoleLogger>();
    services.AddSingleton(typeof(ILog), typeof(MyConsoleLogger));

    services.AddTransient<ILog, MyConsoleLogger>();
    services.AddTransient(typeof(ILog), typeof(MyConsoleLogger));

    services.AddScoped<ILog, MyConsoleLogger>();
    services.AddScoped(typeof(ILog), typeof(MyConsoleLogger));
}

Constructor Injection

Once we register a service, the IoC container automatically performs constructor injection if a service type is included as a parameter in a constructor.
For example, we can use ILog service type in any MVC controller. Consider the following example.
Example: Using Service
public class HomeController : Controller
{
    ILog _log;

    public HomeController(ILog log)
    {
        _log = log;
    }
    public IActionResult Index()
    {
        _log.info("Executing /home/index");

        return View();
    }
}
In the above example, an IoC container will automatically pass an instance of MyConsoleLogger to the constructor of HomeController. We don't need to do anything else. An IoC container will create and dispose an instance of ILog based on the registered lifetime.

Action Method Injection

Sometimes we may only need dependency service type in a single action method. For this, use [FromServices] attribute with the service type parameter in the method.
Example: Action Method Injection
using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
    public HomeController()
    {
    }

    public IActionResult Index([FromServices] ILog log)
    {
        log.info("Index method executing");

        return View();
    }
}

Property Injection

Built-in IoC container does not support property injection. You will have to use third party IoC container.

Get Services Manually

It is not required to include dependency services in the constructor. We can access dependent services configured with built-in IoC container manually using RequestServices property of HttpContext as shown below.
Example: Get Service Instance Manually
public class HomeController : Controller
{
    public HomeController()
    {
    }
    public IActionResult Index()
    {
        var services = this.HttpContext.RequestServices;
        var log = (ILog)services.GetService(typeof(ILog));
            
        log.info("Index method executing");
    
        return View();
    }
}
It is recommended to use constructor injection instead of getting it using RequestServices.
Learn about middleware in the next chapter.

.NET Core Command-Line Interface

Leave a Comment
The .NET Core command-line interface (CLI) is a new cross-platform tool for creating, restoring packages, building, running and publishing .NET applications.
We created our first ASP.NET Core application using Visual Studio in the previous chapter. Visual Studio internally uses this CLI to restore, build and publish an application. Other higher level IDEs, editors and tools can use CLI to support .NET Core applications.
The .NET Core CLI is installed with .NET Core SDK for selected platforms. So we don't need to install it separately on the development machine. We can verify whether the CLI is installed properly by opening command prompt in Windows and writing dotnet and pressing Enter. If it displays usage and help as shown below then it means it is installed properly.

.NET Core Command-line Interface

Command Structure

The following is a command structure.
dotnet <command> <argument> <option>
All the commands start with driver named dotnet. The driver starts the execution of the specified command. After dotnet, we can supply command (also known as verb) to perform a specific action. Each command can be followed by arguments and options. The following are .NET Core 2.x CLI commands.
Basic CommandsDescription
newCreates a new project, configuration file, or solution based on the specified template.
restoreRestores the dependencies and tools of a project.
buildBuilds a project and all of its dependencies.
RunRuns source code without any explicit compile or launch commands.
publishPacks the application and its dependencies into a folder for deployment to a hosting system.
testExecutes unit tests.
vtestRuns tests from the specified files.
packPacks the code into a NuGet package.
cleanCleans the output of a project.
slnModifies a .NET Core solution file.
helpDisplay help on the specified command
storeStores the specified assemblies in the runtime package store.
Project Modification CommandsDescription
add packageAdds a package reference to a project.
add referenceAdds project-to-project (P2P) references.
remove packageRemoves package reference from the project.
remove referenceRemoves project reference
list referenceLists all project-to-project references
Advanced CommandsDescription
nuget deleteDeletes or unlists a package from the server.
nuget localsClears or lists local NuGet resources.
nuget pushPushes a package to the server and publishes it.
msbuildBuilds a project and all of its dependencies.
dotnet install scriptScript used to install the .NET Core CLI tools and the shared runtime.
Let's create, restore, build, and run .NET Core console application using command-line interface without using Visual Studio.

Create a New Project

To create a new .NET Core project, we have to use new command followed by template name argument. We can create console, class library, web, mvc, webapi, razor, angular, react etc. projects using CLI. Use console template to create a new .NET Core console application.
The following creates new console project in the current directory with the same name as current directory.
dotnet new console
The following command creates a new console project named MyConsoleApp. The -n or --name option species the name of a project.
dotnet new console -n MyConsoleApp
The following command creates a new console application named MyConsoleApp to MyProjects directory. The -o or --output option is used to specify an output directory where the project should be generated.
dotnet new console -n MyConsoleApp -o C:\MyProjects
After creating a project, navigate to the project directories in command prompt to apply project specific commands which is C:\MyConsoleApp in our case.

Add Package Reference

We often need to add NuGet package reference for different purposes. For example, apply the following command to add Newtonsoft.json package to our console project.
C:\MyConsoleApp>dotnet add package Newtonsoft.json
This will add Newtonsoft.json package to our project. We can verify it by opening .csproj file.

Restore Packages

To restore packages or to update existing packages, we can use restore command as below.
C:\MyConsoleApp>dotnet restore

Build Project

To build a new or existing project, apply C:\MyConsoleApp>dotnet build command.

Run project

To run our console project, apply dotnet run command as shown below.
As you can see above, it displays an output "Hello World!".

Getting Help

We can get help on any .NET Core CLI commands by typing -h or -help at the end of the command we want to get help on. For example, dotnet new -h will display help on the new command, arguments and options we can use with it, as shown below.

Thus, we can use .NET Core command-line interface to create, restore packages, build, run, and publish different types of .NET Core applications.