封装通用数据源的接口定义

Interface definition for encapsulating a generic data source

我目前正在进行基于 C# 插件的设计,其中插件 API 方法将可以访问包含该方法工作所需的相关信息的上下文对象。在当前的实现中,文件路径被配置为 Context 属性之一,因为它必须提供给主要方法之一,因为它解析文件并加载 API 中的其他方法将使用的信息层次结构.但是 Context 接口中所需的灵活性是能够容纳各种各样的数据源,而不仅仅是基于文件的数据源,例如在稍后的某个时间点,现在以文件形式出现的数据可能会被基于数据库的数据源或网络流,或者由 Web 服务调用返回的 JSON 数据所取代。当前界面如下:

public interface IFlowContext : IPluginContext
{
    string FlowFilePath { get; set; }
    string FlowImportFilePath { get; set; }
}

我在找出足够通用的基于数据源的接口定义来处理所需的灵活性时遇到了一些困难。

有人有什么想法吗?

答案是不要试图创建一个 "generic" 足以满足当前实施设置和未来实施所需设置的界面。每个接口都应该为依赖它的 class 编写。您可能仍然会发现一些共性,您可以在其中重用其中一些接口。例如,您可以根据文件路径对 class 进行不同的实现。但是,如果两个不同的 classes 依赖于两个不同的数据源,那么一个接口应该能够为它们提供设置的原因是零。

不要混淆 - 无论这些文件路径支持什么,应该 是一个可重用的接口。但是这些实现可能需要不同的设置。这需要文件路径。另一个可能需要数据库连接字符串或其他不同的东西。但是这些实现不需要依赖于一些通用接口。它们都应该依赖于一个接口,该接口 "describes" 每个单独的实现都需要什么。

这涉及到接口隔离原则。如果一个实现需要文件路径,它应该依赖于提供文件路径的接口。但是,如果一个实现不需要文件路径,那么它不应该依赖于提供它们的接口。

举例说明:

public interface IGetsSomeData
{
    Data GetSomeData();
}

public class GetsSomeDataFromAFile : IGetsSomeData
{
    private readonly IFilePathSettings _filePathSettings;

    public GetsSomeDataFromAFile(IFilePathSettings filePathSettings)
    {
        _filePathSettings = filePathSettings;
    }

    public DataGetSomeData()
    {
        // read data from a file using a file path
    }
}

public class GetsSomeDataFromSql : IGetsSomeData
{
    private readonly IDatabaseSettings _databaseSettings;

    public GetsSomeDataFromAFile(IDatabaseSettings databaseSettings)
    {
        _databaseSettings = databaseSettings;
    }

    public DataGetSomeData()
    {
        // execute a SQL query using a connection string
    }
}

IGetsSomeData是通用接口。但是实现不需要共享依赖项。也许 SQL 实现甚至不需要接口——它可能只需要一个连接字符串。