繁体   English   中英

接口如何在构造函数依赖注入中发挥作用

[英]How Interface play role in Constructor Dependency Injection

我试图理解基于构造函数的依赖注入的概念。 我已经看到了一些利用接口的constructor based dependency injection代码示例。 在代码片段中,我已经看到服务类构造函数期望使用类型为interface的参数,但是在创建服务类的对象时,将传递实现该接口的类的实例。 那么,如何在运行时将类的类型转换为接口的类型,或者还有其他东西呢? 幕后发生了什么?

让我分享一些示例代码-

介面-

实现简单的界面

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

储存库-

仓库类实现接口

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

服务-

服务类期望在创建对象时传递IRepoInterface

namespace constructor_di
{
    class Service
    {
        private readonly IRepoInterface _repo;

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

程序启动-

在这里创建Service类的实例

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

通过构造函数进行依赖注入是减少紧密耦合并提高代码可测试性的好方法。 您甚至不需要使用依赖项注入容器。 在您的组合根目录中,指定要使用哪些实现这些接口的类,并将它们注入其使用者。

然后,具有表示为合同的依存关系的类仅关心合同指定的行为。 它不关心实现细节。

这使您能够使用实现相同接口的装饰器来增强基本行为,并添加其他功能,而无需修改先前的/基本实现本身。

而且,在单元测试中,您可以使用某种模拟/伪造的实现来隔离依赖关系,并更轻松地测试使用者本身。

关于你的问题:

那么,如何在运行时将类的类型转换为接口的类型,或者还有其他东西呢? 幕后发生了什么?

如果一个类实现了一个接口,则可以在不进行任何强制转换的情况下将其注入使用类。 编译器确保您仅与接口公开的成员进行交互。

进一步阅读: https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/interfaces/

接口是合同,其中定义了一些成员的签名。 它与它们的实现无关。 因此,任何实现该接口的类都在履行合同,因此它的对象是该接口类型或实现该接口的类的类型检查的有效替代。

例-

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);
    }
}

在上面的代码片段中,BaseRepository类实现了Interface,而ChildRepository类扩展了BaseRepository类。

因此,ChildRepository类的任何对象都将通过以进行ChildRepository,BaseRepository和IRepoInterface的类型检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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