如何修复这种循环依赖?
How do I fix this circular dependency?
我在 Gary McLean Hall 的 Adaptive Code via C# 单元 testing/test-driven 开发部分。我的问题是基于书中可能包含错误的示例。以下是 3 层架构中 AccountService
示例的 UML 图:
我将我的解决方案分为四个不同的项目,对应于层:User_Interface、Business_Logic、Data_Access 和 Unit_Tests。
我的问题与 IAccountRepository
界面有关。在书中,作者为伪造的 class(在 Unit_Tests 项目中)编写了以下代码,用于模拟 IAccountRepository
接口的实现以用于单元测试:
class FakeAccountRepository : IAccountRepository
{
private Account account;
public FakeAccountRepository(Account account)
{
this.account = account;
}
public Account GetByName(string accountName)
{
return account;
}
}
我遇到的问题是 GetByName()
方法 return 是 Account
类型。如果我尝试将 IAccountRepository
中的签名更改为 Account
return 类型,它找不到该类型。由于 Account
class 是业务逻辑层的一部分,如果我尝试添加对 Business_Logic 项目的引用(来自 Data_Access 项目),Visual Studio 给我一个 "circular dependency" 错误。
这是有道理的,因为数据访问层是底层,不应该依赖于它上面的任何层...但是没有引用我不能在IAccountRepository
界面。
作者是不是忘记了什么?我是否应该创建一个 IAccount
接口,将 GetByName()
方法更改为 return 一个 IAccount
类型,并让 Account
实现 IAccount
接口?如果没有,我该如何解决?
我在这里看到两种可能性:
- 添加名为 "Common" 或类似名称的项目 - 将帐户 class 存储在那里,并在两个 [=12] 中添加对 Common 的引用=]数据访问和业务逻辑项目
- 为帐户创建两个 classes:一个在数据访问中,一个在业务逻辑中。两者将具有相同的字段(属性)。第二个 class 应该是名称 AccountModel。
这是我在专业解决方案中看到的方法。基本上,数据访问层有实体classes,业务逻辑层有模型classes。当服务从存储库中获取数据时,它将 Account 类型的对象映射到 AccountModel
类型的对象
很可能作者将其编写为单个可执行文件并将所有内容都放在一个项目中,因此数据访问层对帐户可见 class。
您可以自己完成此操作,只需将 "layers" 分成不同的命名空间以提供逻辑分离。
我最终采用了与此处答案不同的方法。我在数据访问层创建了一个名为 IAccount
的接口,并使用 IAccount
作为 GetByName()
方法的 return 类型。这解决了我的问题,并且仍然保持分层架构。
我在 Gary McLean Hall 的 Adaptive Code via C# 单元 testing/test-driven 开发部分。我的问题是基于书中可能包含错误的示例。以下是 3 层架构中 AccountService
示例的 UML 图:
我将我的解决方案分为四个不同的项目,对应于层:User_Interface、Business_Logic、Data_Access 和 Unit_Tests。
我的问题与 IAccountRepository
界面有关。在书中,作者为伪造的 class(在 Unit_Tests 项目中)编写了以下代码,用于模拟 IAccountRepository
接口的实现以用于单元测试:
class FakeAccountRepository : IAccountRepository
{
private Account account;
public FakeAccountRepository(Account account)
{
this.account = account;
}
public Account GetByName(string accountName)
{
return account;
}
}
我遇到的问题是 GetByName()
方法 return 是 Account
类型。如果我尝试将 IAccountRepository
中的签名更改为 Account
return 类型,它找不到该类型。由于 Account
class 是业务逻辑层的一部分,如果我尝试添加对 Business_Logic 项目的引用(来自 Data_Access 项目),Visual Studio 给我一个 "circular dependency" 错误。
这是有道理的,因为数据访问层是底层,不应该依赖于它上面的任何层...但是没有引用我不能在IAccountRepository
界面。
作者是不是忘记了什么?我是否应该创建一个 IAccount
接口,将 GetByName()
方法更改为 return 一个 IAccount
类型,并让 Account
实现 IAccount
接口?如果没有,我该如何解决?
我在这里看到两种可能性:
- 添加名为 "Common" 或类似名称的项目 - 将帐户 class 存储在那里,并在两个 [=12] 中添加对 Common 的引用=]数据访问和业务逻辑项目
- 为帐户创建两个 classes:一个在数据访问中,一个在业务逻辑中。两者将具有相同的字段(属性)。第二个 class 应该是名称 AccountModel。 这是我在专业解决方案中看到的方法。基本上,数据访问层有实体classes,业务逻辑层有模型classes。当服务从存储库中获取数据时,它将 Account 类型的对象映射到 AccountModel 类型的对象
很可能作者将其编写为单个可执行文件并将所有内容都放在一个项目中,因此数据访问层对帐户可见 class。
您可以自己完成此操作,只需将 "layers" 分成不同的命名空间以提供逻辑分离。
我最终采用了与此处答案不同的方法。我在数据访问层创建了一个名为 IAccount
的接口,并使用 IAccount
作为 GetByName()
方法的 return 类型。这解决了我的问题,并且仍然保持分层架构。