Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection and use of default constructor

I am trying to understand Dependency Injection concept. Below is the example I am trying to debug. Here I have created Customer class whose dependencies I have Injected in his constructor Now when i called this.Iorder.GetOrderDetails(); in the Index method it is giving me error of NullReferenceException and asking to use new keyword to create an object to call the method. When I moved this call this.Iorder.GetOrderDetails(); to another method GetCutomerDetails() and call that method in Index Method it works.

Question: I am not able to understand why this.Iorder.GetOrderDetails() method call is not working in Index method and why it is working in GetCutomerDetails()

public  interface IorderDetails
{
    void GetOrderDetails();
}

public class CustomerModel : IorderDetails
{
    public void GetOrderDetails() {}
}

Controller:

public class CustomerController: Controller
{
    private IorderDetails Iorder;

    //DI constructor  Injecting OrderDetails object 
    CustomerController(IorderDetails iorderObj)
    {
        if (iorderObj == null)
            throw new ArgumentNullException("orderObj should not be null");

        this.Iorder = iorderObj;
    }
    //Default constructor  
    public CustomerController() { }

    public ActionResult Index()
    {            
       CustomerController objCustomer = new CustomerController(new CustomerModel());
       objCustomer.GetCutomerDetails();

       //Commented GetOrderDetails() method
       //this.Iorder.GetOrderDetails();            
       return View();
    }

    public ActionResult GetCutomerDetails()
    {
        this.Iorder.GetOrderDetails();
        return View();
    }
}
like image 596
user2773364 Avatar asked Nov 02 '22 14:11

user2773364


1 Answers

You have default constructor for CustomerController. When it is called, you don't assign anything to Iorder. So it is null in that case. After that in method Index() you try to execute method GetOrderDetails() using Iorder, which is null. This fails. When you create another instance of CustomerController inside method Index(), you can call GetOrderDetails() on that instance.

In general, using multiple constructors is not advised when combined with Dependency Injection. But when it is necessary, you should initialize all instance fields to something that works. This is called a local default. An excellent book on Dependency Injection patterns and anti-patterns is Dependency Injection in .NET. Also take a look at the blog of its author.

like image 199
Roman Boiko Avatar answered Nov 08 '22 06:11

Roman Boiko