【发布时间】:2012-02-18 00:18:51
【问题描述】:
我正在针对一个系统进行开发,该系统提供访问其数据库的 Web 服务并通过 .NET 类公开该服务。我们通常的工作方式是在需要访问数据库并直接使用该实例时创建 Web 服务类的实例;这当然完全违背了 IoC 并创建了大部分不可测试的代码。我现在正在尝试设计一种使用 IoC 的新标准工作方式,以使我们能够编写(更多)SOLID 代码。
我目前的解决方案是这样的(解释得不是很好):
Web 服务封装在 DatabaseConnection 类中,该类将 Web 服务对象存储为受保护的成员,并提供对许多常用通用数据库调用的访问。
当我需要在实际应用程序中访问数据库时,我从该类派生(调用新类,例如 ApplicationDatabaseConnection)并在能够调用 Web 服务的方法中实现所需的数据库交互。
此类不直接在应用程序中使用,而是为应用程序的不同部分提供“连接器”接口,每个部分由顶层的控制器/视图模型类表示。每当调用其中一个应用程序功能时(例如从 UI 调用),就会创建相应的控制器对象并将我的 ApplicationDatabaseConnection 对象作为相应“连接器”接口的实现传递,因此数据库访问在此时被正确封装和解耦,据我所知。
我的问题是:虽然这是我在自己的代码中发现 ISP(接口隔离原则)实际使用的第一个案例(尽管我不确定这是否真的合理使用该概念),恐怕这个类可能做的太多,违反了 SRP(单一责任原则)。还是“仅提供数据库访问权限,尽管针对许多不同的消费者”是一项单一职责?
为了更清楚一点,以下是相关类的大致样子:
DatabaseConnection
protected m_webservice
public OftenUsedDatabaseAccess()
ApplicationDatabaseConnection : DatabaseConnection, IConnectorA, IConnectorB
public IConnectorA.RetrieveRecords(fieldValue)
public IConnectorB.WriteStuff(listOfStuff)
FunctionAController
private m_IConnectorA
FunctionBController
private m_IConnectorB
我能想到的替代方案对我来说似乎也不理想。
为了拆分数据库访问功能,ApplicationDatabaseConnection 类只能是具有用于不同连接器的Create 方法的工厂类(在IConnectorAFactory、IConnectorBFactory 接口后面)——但实际上并没有什么可做的需要工厂模式;我只有在实例化“控制器”对象时才知道。
此外,实际的连接器类本质上也需要是 DatabaseConnection 的派生类,因为它们需要相同的基本能力,然后(最迟)整个构造变得相当不祥。
我想我的想法在某个时候走错了方向,现在完全走错了路。这种解决方案的结构应该是什么样的?任何朝着正确方向的推动都将不胜感激。
编辑:
@Tobias 的回答让我意识到我忘记了一个重要的细节:有两个不同版本的 Web 服务具有几乎相同的功能,但 API 完全不同,这也是它 具有的原因之一em> 被封装。
另一个问题是,如果我的逻辑类直接(或通过接口)访问 Web 服务,它们还关心构建 Web 服务查询的所有细节,这使得代码耦合更紧密(我们'到目前为止一直在生产)并且违反了 SRP - 因此是连接器接口的想法。
【问题讨论】:
标签: .net oop dependency-injection inversion-of-control single-responsibility-principle