简体   繁体   中英

How Interface play role in Constructor Dependency Injection

I'm trying to understand the concept of constructor-based dependency injection. I have seen a few code samples of constructor based dependency injection utilizing the interfaces. In the code snippet I've seen that a service class constructor expects a parameter of type interface but while creating the object of service class, the instance of a class is passed which implements that interface. So how come at runtime the type of class is being cast to the type of interface or is there something else? What's happening behind the scene?

Let me share some sample code -

Interface -

Simple interface to be implemented

namespace constructor_di
{
    interface IRepoInterface
    {
        string test();
    }
}

Repository -

Repository class implementing interface

namespace constructor_di
{
    class Repository : IRepoInterface
    {
        public string test()
        {
            return "Test String";
        }
    }
}

Service -

Service class expecting IRepoInterface to be passed while creating object

namespace constructor_di
{
    class Service
    {
        private readonly IRepoInterface _repo;

        public Service(IRepoInterface repoInterface)
        {
            _repo = repoInterface;
        }
    }
}

Program Startup -

Creating instance of Service class here

namespace constructor_di
{
    class Program
    {
        static void Main(string[] args)
        {
            Service obj = new Service(new Repository());
        }
    }
}

Dependency injection via constructors is a great way to minimize tight coupling and increase testability of your code. You don't even need to use a dependency injection container; in your composition root, you specify which classes implementing those interfaces are going to be used and inject them into their consumers.

A class that has a dependency expressed as a contract then only cares about the behavior specified by the contract. It does not care about the implementation details.

This enables you to enhance the base behavior with decorators that implement the same interface and add additional functionality without modifying the previous / base implementation itself.

And, in unit tests, you can isolate the dependencies using some kind of mock / fake implementations and test the consumer itself more easily.

As to your question:

So how come at runtime the type of class is being cast to the type of interface or is there something else? What's happening behind the scene?

If a class implements an interface, it can be injected into the consuming class without any casting. The compiler ensures that you only interact with the members exposed by the interface.

Further reading: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/

Interface is a contract with some member's signature defined in them. It has nothing to do with their implementations. So any class implementing the interface is fulfilling the contract & thus it's object is a valid replacement for type checking of that interface type or classes implementing that interface.

Example-

using System;

interface IRepoInterface
{
    string test();
}

class BaseRepository : IRepoInterface
{
    public string test()
    {
        return "Test String in implementing class";
    }
}

class ChildRepository : BaseRepository
{
    public string SomeFunctionName()
    {
        return "Test String in child class";
    }
}

public class Program
{
    public static void Main()
    {
        ChildRepository repo = new ChildRepository();
        Console.WriteLine(repo is ChildRepository);
        Console.WriteLine(repo is BaseRepository);
        Console.WriteLine(repo is IRepoInterface);
    }
}

In above code snippet, class BaseRepository implements the Interface and class ChildRepository extends class BaseRepository.

So any object of class ChildRepository will pass for type checking for ChildRepository, BaseRepository and IRepoInterface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM