Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何修复此循环依赖关系?_C#_Unit Testing_Tdd_Dependency Management - Fatal编程技术网

C# 如何修复此循环依赖关系?

C# 如何修复此循环依赖关系?,c#,unit-testing,tdd,dependency-management,C#,Unit Testing,Tdd,Dependency Management,我在Gary McLean Hall的《通过C实现自适应代码》的单元测试/测试驱动开发部分。我的问题基于书中可能包含错误的一个例子。以下是3层体系结构中AccountService示例的UML图: 我将我的解决方案分为四个不同的项目,分别对应于这些层:用户界面、业务逻辑、数据访问和单元测试 我的问题与IAccountRepository接口有关。在本书中,作者为Unit_Tests项目中的一个伪类编写了以下代码,该项目用于模拟IAccountRepository接口的实现,以用于单元测试: cl

我在Gary McLean Hall的《通过C实现自适应代码》的单元测试/测试驱动开发部分。我的问题基于书中可能包含错误的一个例子。以下是3层体系结构中AccountService示例的UML图:

我将我的解决方案分为四个不同的项目,分别对应于这些层:用户界面、业务逻辑、数据访问和单元测试

我的问题与IAccountRepository接口有关。在本书中,作者为Unit_Tests项目中的一个伪类编写了以下代码,该项目用于模拟IAccountRepository接口的实现,以用于单元测试:

class FakeAccountRepository : IAccountRepository
{    
   private Account account;

   public FakeAccountRepository(Account account)
   {
       this.account = account;
   }

   public Account GetByName(string accountName)
   {
       return account;
   }
}
我遇到的问题是GetByName方法返回帐户类型。如果我尝试将IAccountRepository中的签名更改为帐户返回类型,它将找不到该类型。由于Account类是业务逻辑层的一部分,如果我试图从Data_Access项目中添加对业务逻辑项目的引用,Visual Studio会给我一个循环依赖性错误

这是有意义的,因为数据访问层是底层,不应该依赖于自身之上的任何层……但是如果没有引用,我就无法在IAccountRepository接口中拥有帐户返回类型


作者是不是忘了什么?我应该创建一个IAccount接口,更改GetByName方法以返回IAccount类型,并让Account实现IAccount接口吗?如果没有,我如何解决这个问题?

我在这里看到两种可能性:

添加一个名为Common或类似的项目-将Account类存储在那里,并在数据访问和业务逻辑项目中添加对Common的引用 为Account创建两个类:一个在数据访问中,一个在业务逻辑中。两者将具有相同的字段属性。第二个类应该是name AccountModel。 这是我在专业解决方案中看到的方法。基本上,数据访问层有实体类,业务逻辑层有模型类。当服务从存储库获取数据时,它将Account类型的对象映射到AccountModel类型的对象
我在这里看到两种可能性:

添加一个名为Common或类似的项目-将Account类存储在那里,并在数据访问和业务逻辑项目中添加对Common的引用 为Account创建两个类:一个在数据访问中,一个在业务逻辑中。两者将具有相同的字段属性。第二个类应该是name AccountModel。 这是我在专业解决方案中看到的方法。基本上,数据访问层有实体类,业务逻辑层有模型类。当服务从存储库获取数据时,它将Account类型的对象映射到AccountModel类型的对象
很可能作者是将其作为单个可执行文件编写的,并且在单个项目中拥有所有内容,因此数据访问层对account类具有可见性


您可以自己这样做,只需将层分隔为不同的名称空间,以提供逻辑分隔。

很可能作者将其作为单个可执行文件编写,并将所有内容都包含在单个项目中,因此数据访问层对account类具有可见性


您可以自己这样做,只需将层分隔为不同的名称空间,以提供逻辑分隔。

我最终采用了与此处答案不同的方法。我在数据访问层创建了一个名为IAccount的接口,并使用IAccount作为GetByName方法的返回类型。这解决了我的问题,并且仍然保持了分层的体系结构。

我最终采取了与这里的答案不同的方法。我在数据访问层创建了一个名为IAccount的接口,并使用IAccount作为GetByName方法的返回类型。这解决了我的问题,仍然保持了分层结构。

感谢您的回复。本示例前面的章节介绍了多层体系结构/依赖关系管理的最佳实践,以及每一层应该如何在自己的组件中。这是本书的一个主要主题。因此,我不认为作者在一个项目中完成了所有工作……而且,将应用程序分离为名称空间而不是项目将如何解决DAL仍然需要依赖于业务逻辑层这一事实,这违背了DAL不应依赖于自身之上任何层的原则?这就是理论击中实际应用的地方。您必须在复制代码、为每个项目创建Account类和创建包含不同层之间共享的代码的共享库之间进行选择。这是微服务体系结构的一个常见问题。编辑:创建共享库将创建依赖项,但它将允许独立程序集。重复类将允许独立的
在这种体系结构中,存储库层应该有自己的DTO。然后,业务层在写入/读取时将is业务对象帐户转换为存储库帐户DTO。您可以使用automapper之类的库来避免编写繁琐的翻译代码。这是这种架构的缺点。因此,您的IAccountRepository中缺少一个AccountDto。一旦你有了这些,你可以删除对你的BL的依赖。谢谢你的回复。本示例前面的章节介绍了多层体系结构/依赖关系管理的最佳实践,以及每一层应该如何在自己的组件中。这是本书的一个主要主题。因此,我不认为作者在一个项目中完成了所有工作……而且,将应用程序分离为名称空间而不是项目将如何解决DAL仍然需要依赖于业务逻辑层这一事实,这违背了DAL不应依赖于自身之上任何层的原则?这就是理论击中实际应用的地方。您必须在复制代码、为每个项目创建Account类和创建包含不同层之间共享的代码的共享库之间进行选择。这是微服务体系结构的一个常见问题。编辑:创建共享库将创建依赖项,但它将允许独立程序集。重复的类将允许独立的程序集,但使管理代码更改更加困难。在这种体系结构中,存储库层应该有自己的DTO。然后,业务层在写入/读取时将is业务对象帐户转换为存储库帐户DTO。您可以使用automapper之类的库来避免编写繁琐的翻译代码。这是这种架构的缺点。因此,您的IAccountRepository中缺少一个AccountDto。一旦你有了这些,你可以删除对你的BL的依赖。谢谢你的回复。添加对公共项目的引用不会创建对它的依赖吗?我正在努力学习最佳实践,书中特别提到DAL应该能够在没有其他层的情况下独立运行。DAL上方的层依赖于DAL,但DAL不能依赖于其上方的层。因此,我更倾向于选择2。你认为这是作者的意图吗?选项2似乎是更好的选择-正如你所提到的,它使DAL成为一个独立的功能包。普通项目会把事情搞得一团糟,所以我不会真正使用它——它是用来指出第二种方法的优点的。关于作者的缩进,我只能猜测。也许他想让读者自己修复它,正如下面提到的@Robert——作者可以把所有东西都放在一个项目中,但名称空间不同。我认为这是一个很好的演示,教育目的。谢谢你的回复。添加对公共项目的引用不会创建对它的依赖吗?我正在努力学习最佳实践,书中特别提到DAL应该能够在没有其他层的情况下独立运行。DAL上方的层依赖于DAL,但DAL不能依赖于其上方的层。因此,我更倾向于选择2。你认为这是作者的意图吗?选项2似乎是更好的选择-正如你所提到的,它使DAL成为一个独立的功能包。普通项目会把事情搞得一团糟,所以我不会真正使用它——它是用来指出第二种方法的优点的。关于作者的缩进,我只能猜测。也许他想让读者自己修复它,正如下面提到的@Robert——作者可以把所有东西都放在一个项目中,但名称空间不同。我认为这对于演示和教育目的来说是很好的。