Thursday, March 28, 2019

C# : What is Dependency Injection

This blog will give a quick introduction of Dependency injection pattern and when and how to use it with example.

Dependency injection is technique which provides or inject an object that will be dependency of another object, first let us understand what dependency is with example in C # code. 

When we write a class ‘X’ and this class uses the functionality of another class Y, then it is called the Class X has a dependency of Class Y.

May be Class X uses Class Y to make any External Web API calls or any database call or it could be Class Y have some business rules so while using the Class Y ‘s functionalities, Class X has code to construct Class Y object.

  
Dependency Injection


above pic depicts how Class X uses Class Y to perform the database related operation and uses Class Z to perform external service call operations.

In Real World Example, we have an OrderModule programming code, which basically responsible for order place and cancel order and during order place, it calls Inventory service to check Item availability and also call Customer service to find customer information.

C# Code:

public class OrderModule : IOrderModule
    {
        CustomerAPI customerAPI;
        InventoryAPI inventoryAPI;
        OrderRepository orderRepository;

        public OrderModule()
        {
             customerAPI = new CustomerAPI();
             inventoryAPI = new InventoryAPI();
             orderRepository = new OrderRepository();
        }

        public int PlaceOrder(Order order)
        {
            Customer customer = _customerAPI.GetCustomer(order.CustomerNumber);

            if (customer != null)
            {
                Item item = _inventoryAPI.getItemDetails(order.ItemNumber);
                if (item.AvailableInStock)
                {
                    int orderNumber = _orderRepository.PlaceOrder(order);
                    return orderNumber;
                }
                else
                {
                    throw new Exception("Out of Order.");
                }
            }
            else
            {
                throw new Exception("Customer Not Found.");
            }

        }      
    }


In above Code,  OrderModule class uses the CustomerAPI class functionality - get customer information and uses the InventoryAPI class functionality  - check item availability in stock  to place customer order. So these classes are dependency of OrderModule Class.

So before using the functionalities of these class, we need to create object of these class in orderModule class. Now to delegate these object creation task to someone other and it will supply the objects (of dependency of class), this technique is called dependency injection

In rest part of this post, we will discuss about the unity and how to inject dependency of class.

In SOLID Principle, Dependency Inversion Principle says Details Class should depends on abstract (interface) instead of concrete class.

Let refactor above code:
1.       Create Abstract type of Each Dependency Class. Eg ICustomerAPIIInventoryAPI & IOrderRepository

C# Code:

public interface ICustomerAPI
    {
        Customer GetCustomer(int customerNumber);
    }

public interface IInventoryAPI
    {
        Item getItemDetails(int itemNumber);
    }

public interface IOrderRepository
          {
              int PlaceOrder(Order order);
              int CancellOrder(Order order);
       }

2.       Use Abstract Type (Interface) in place of Concreate Class in object.
3.       Use Dependency Injection to create object of dependency class.

after above code changes, Class depends on interface instead of concreate class and DI will be worked as middle man to create object and inject those at runtime and now Object is completely independent for creating of object and you can use unity to implement the dependency injection 

C# Code:

public class OrderModule : IOrderModule
    {
        ICustomerAPI _customerAPI;
        IInventoryAPI _inventoryAPI;
        IOrderRepository _orderRepository;

        public OrderModule(ICustomerAPI customerAPIIInventoryAPI inventoryAPIIOrderRepository orderRepository)
        {
            _customerAPI = customerAPI;
            _inventoryAPI = inventoryAPI;
            _orderRepository = orderRepository;
        }

        public int PlaceOrder(Order order)
        {
            Customer customer = _customerAPI.GetCustomer(order.CustomerNumber);

            if (customer != null)
            {
                Item item = _inventoryAPI.getItemDetails(order.ItemNumber);
                if (item.AvailableInStock)
                {
                    int orderNumber = _orderRepository.PlaceOrder(order);
                    return orderNumber;
                }
                else
                {
                    throw new Exception("Out of Order.");
                }
            }
            else
            {
                throw new Exception("Customer Not Found.");
            }

        }
      

No comments:

SQL Server - Identify unused indexes

 In this blog, we learn about the index usage information (SYS.DM_DB_INDEX_USAGE_STATS) and analyze the index usage data (USER_SEEKS, USER_S...