为什么要为此配置类创建一个接口?

use*_*696 6 c# oop design-patterns .net-core asp.net-core

我对接口的理解是它们定义了契约,而实现该接口的类则对契约进行签名。在这种情况下,我们可以将类设计为依赖于合同而不是具体的实现。这具有减少耦合,启用多态性等优点。

现在,我遇到了一种我没有得到的接口。这是来自ASP.NET Core文档中有关配置的信息。特别是在该页面中,人们正在谈论使用ASP.NET Core设置MongoDB。

他们基本上定义了一个类和一个接口,如下所示:

namespace BooksApi.Models
{
    public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings
    {
        public string BooksCollectionName { get; set; }
        public string ConnectionString { get; set; }
        public string DatabaseName { get; set; }
    }

    public interface IBookstoreDatabaseSettings
    {
        string BooksCollectionName { get; set; }
        string ConnectionString { get; set; }
        string DatabaseName { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后他们按如下方式使用它:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<BookstoreDatabaseSettings>(
        Configuration.GetSection(nameof(BookstoreDatabaseSettings)));

    services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
        sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);

    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
Run Code Online (Sandbox Code Playgroud)

我必须说我不明白。类型的对象应用BookstoreDatabaseSettings作设置的DTO。它们根本不提供任何功能。那么为什么要在中间引入一个接口呢?

我在这里看不到一种用法,可以在其他用法上使用。我在这里看不到为什么要尝试将其解耦,我根本看不到多态性的任何使用,而且我确实没有明白这一点。

那么为什么在这种情况下,当处理ASP.NET Core中的设置时,人们直接使用接口而不使用具体的类(例如BookstoreDatabaseSettings)?

Chr*_*att 8

在仅一个应用程序的上下文中,您是正确的,这没有任何意义。但是,可能存在某些情况。

这里发生的是,首先,将BookstoreDatabaseSettings其绑定到config部分。从技术上讲,这就是所需要的。然而,这种使用模式的选项,这意味着你必须再injnect IOptions<BookstoreDatabaseSettings>IOptionsSnapshot<BookstoreDatabaseSettings>等等,而不是BookstoreDatabaseSettings直接。这意味着对的依赖Microsoft.Extensions.Options,这不是一件坏事,但这仍然是一个依赖。

然后,下一行将接口绑定到BookstoreDatabaseSettings从中拉出的实际实例IOptions<BookstoreDatabaseSettings>。换句话说,您现在可以简单地注入接口,而不是IOptions<BookstoreDatabaseSettings。再说一次,没有什么大不了的,但是它抽象了的使用Microsoft.Extensions.Options。对于它的价值,您可以很容易地注册,BookstoreDatabaseSettings而不是通过接口获得相同的东西。然后,您可以BookstoreDatabaseSettings直接注入,而无需依赖Microsoft.Extensions.Options

接口在这里为您提供的是抽象实际的类实现。您可以将接口单独放在项目之间共享的库中,并将实际的类实现留给每个单独的项目。如果共享库仅依赖于接口,则提供的实际实现将无关紧要。但是,您也可以轻松地在项目之间共享类的实现。这只是一个观点问题。