c# - 为什么要为这个配置类创建一个接口?
问题描述
我对接口的理解是它们定义了合约,实现接口的类签署了合约。在这种情况下,我们可以设计类来依赖于契约而不是具体的实现。这具有减少耦合、启用多态性等优点。
现在我遇到了一种我没有得到的接口用法。这是关于配置的 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; }
}
}
然后他们按如下方式使用它:
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);
}
我必须说我不会得到它。类型的对象BookstoreDatabaseSettings
旨在用作设置的 DTO。它们根本不提供任何功能。那么为什么要在中间引入一个接口呢?
我在这里看不到一种使用其他实现的用法。我在这里不明白为什么要尝试解耦,我根本看不到多态性的任何用途,而且我真的不明白这一点。
那么为什么在这种情况下,在处理 ASP.NET Core 中的设置时,直接使用接口而不是具体类(例如BookstoreDatabaseSettings
)?
解决方案
在只有一个应用程序的情况下,您说这没有意义是正确的。但是,在某些情况下可能会出现这种情况。
这里发生的是,首先,BookstoreDatabaseSettings
绑定到配置部分。从技术上讲,这就是所有需要的。但是,这使用选项模式,这意味着您必须然后 injnectIOptions<BookstoreDatabaseSettings>
等IOptionsSnapshot<BookstoreDatabaseSettings>
,而不是BookstoreDatabaseSettings
直接。这意味着对 的依赖Microsoft.Extensions.Options
,这不一定是坏事,但它仍然是依赖。
下一行然后将接口绑定到实际BookstoreDatabaseSettings
实例,从IOptions<BookstoreDatabaseSettings>
. 换句话说,您现在可以简单地注入接口,而不是IOptions<BookstoreDatabaseSettings
. 同样,没有什么纪念意义的,但它抽象了Microsoft.Extensions.Options
. 对于它的价值,你可以很容易地注册BookstoreDatabaseSettings
而不是界面来获得同样的东西。然后,您将能够BookstoreDatabaseSettings
直接注入,而无需依赖Microsoft.Extensions.Options
.
接口在这里给你带来的是抽象实际的类实现。您可以将接口单独放在项目之间共享的库中,并将实际的类实现留给每个单独的项目。如果您的共享库仅依赖于接口,那么提供的实际实现将无关紧要。但是,您也可以轻松地在项目之间共享类实现。这只是一个观点问题。
推荐阅读
- c++ - 无法在动态链接库 KERNEL32.dll 中找到过程入口点 K32EnumProcessModules
- python - 找到“M”并将数字乘以 100 万,然后找到“B”并将数字乘以 10 亿
- javascript - Gatsby 动态内容和模式拼接
- sql - 当我有多个结果时,为什么这个 powershell 代码只返回一个结果?
- laravel - Laravel 5.8 .env.testing 文件不工作
- ios - UIPanGestureRecognizer 弹出 UIViewController
- git - 在 Github 上更改拉取请求的基本分支时会删除哪些提交?
- r - 使用基于组的汇总值创建新变量
- html - 下载为 TSV 时更改谷歌电子表格的文件名
- c++ - 优雅的 C++ 代码:如何使用 while 循环和条件语句编写更高效的代码