C# 我对接口感到困惑吗?

C# 我对接口感到困惑吗?,c#,interface,C#,Interface,我正在维护一个ASP.NET MVC项目。在这个项目中,最初的开发人员拥有大量的接口。例如:IOrderService,IPaymentService,IEmailService,IResourceService。我感到困惑的是,每一个都只由一个类实现。换言之: OrderService : IOrderService PaymentService : IPaymentService 我对接口的理解一直是,它们被用来创建一个可以轻松交换组件的体系结构。比如: Square : IShape C

我正在维护一个ASP.NET MVC项目。在这个项目中,最初的开发人员拥有大量的接口。例如:
IOrderService
IPaymentService
IEmailService
IResourceService
。我感到困惑的是,每一个都只由一个类实现。换言之:

OrderService : IOrderService
PaymentService : IPaymentService
我对接口的理解一直是,它们被用来创建一个可以轻松交换组件的体系结构。比如:

Square : IShape
Circle : IShape
此外,我不明白这些是如何创建和使用的。以下是OrderService:

public class OrderService : IOrderService
{
    private readonly ICommunicationService _communicationService;
    private readonly ILogger _logger;
    private readonly IRepository<Product> _productRepository;

    public OrderService(ICommunicationService communicationService, ILogger logger,
        IRepository<Product> productRepository)
    {
        _communicationService = communicationService;
        _logger = logger;
        _productRepository = productRepository;
    }
}
public类OrderService:IOrderService
{
专用只读ICommunicationService\u通信服务;
专用只读ILogger\u记录器;
私有只读IRepository\u productRepository;
公共订购服务(ICommunicationService通信服务、ILogger记录器、,
i存储产品存储库)
{
_通信服务=通信服务;
_记录器=记录器;
_productRepository=productRepository;
}
}

这些对象似乎永远不会直接创建,因为在
OrderService OrderService=new OrderService()
中,它总是使用接口。我不明白为什么要使用接口而不是实现接口的类,或者它是如何工作的。在我的谷歌技能没有揭示的界面方面,我有没有遗漏一些重要的东西?

这不是界面的唯一用途,在MVC中,它们被用来将契约与实现分离。要了解MVC,您需要阅读一些相关主题,如关注点分离和控制反转(IoC)。创建要传递给
OrderService
构造函数的对象的实际操作由IoC容器根据一些预定义的映射进行处理

这些对象似乎永远不会像在OrderService OrderService=new中那样直接创建 OrderService()

那又怎么样

关键是有人调用OrderService构造函数,调用方负责创建它们。他把它们交给我

我不明白为什么使用接口而不是实现 接口

因为您不想知道类-它可能会更改,是外部的,可以使用IOC容器进行配置,程序员甚至不需要公共基类。您对某人如何实现使用过的实用程序类的假设越少越好

在我的谷歌技能所不具备的界面方面,我是否缺少一些重要的东西 揭露


不,一本关于OO编程的好书比随机的谷歌代码片段更有帮助。这可以分为体系结构领域和.NET基础知识(第一部分)。

这种特殊的设计模式通常是为了方便单元测试,因为您现在可以用TestOrderService替换OrderService,这两种模式都仅作为IOrderService引用。这意味着您可以编写TestOrderService为被测类提供特定的行为,然后判断被测类是否在做正确的事情

在实践中,上述工作通常通过使用模拟框架来完成,因此您实际上不需要手工编写TestOrderService代码,而是使用更简洁的语法来描述它在典型测试中的行为,然后让模拟框架为您动态生成实现


至于为什么您在代码中从来没有看到“neworderservice”,很可能您的项目正在使用某种形式的控制反转容器,这有助于自动依赖项注入。换句话说,您不必直接构造OrderService,因为您已经在某个地方配置了IOrderService的任何使用都应该通过构造singleton OrderService并将其传递给构造函数来自动完成。这里有很多微妙之处,我不确定依赖项注入是如何完成的(它不一定是自动的;您也可以手动构造实例并通过构造函数传递它们。)

根据接口而不是对象编程是一种很好的做法。这个问题给出了很好的理由,但有些理由包括允许实现更改(例如测试)

仅仅因为目前只有一个类实现了该接口,并不意味着它将来不能更改

此外,我不明白这些是如何创建和使用的


这被调用,基本上意味着类不需要知道如何或从何处实例化它的依赖项,其他人将处理它。

这些是服务接口,封装了某种外部性。您的主项目中通常只有它们的一个实现,但是您的测试使用不依赖于外部内容的更简单的实现

例如,如果您的支付服务联系paypal验证支付,您不希望在测试无关代码时进行验证。相反,您可以将它们替换为一个简单的实现,该实现始终返回“payment worked”并检查订单流程是否通过,另一个实现返回“payment failed”并检查订单流程是否也失败

为了避免依赖于实现,您不自己创建实例,而是在构造函数中接受它们。然后,创建类的IoC容器将填充它们。抬头看


您的项目可能有一些在其启动代码中设置IoC容器的代码。该代码包含了当您需要某个接口的实现时要创建哪个类的信息。

也许这个想法是使用接口,这样业务对象就可以被简单的单元测试所替代(但从来没有做到这一点)?如果