我的C#项目中的循环引用

我有以下情况:

  1. 一个项目MyCompany.MyProject.Domain ,它包含我的域模型和部分类(如Contact )。

  2. 我希望’扩展’(通过部分类,而不是扩展方法)我的Contact类具有属性Slug ,它将为我提供一个简单的URL友好文本表示的名字和姓氏。

  3. 我在我的Utility项目MyCompany.MyProject.Utilities有一个字符串扩展方法ToSlug() ,它完全符合我想要的2)。

  4. 问题:My Utility项目已经引用了我的Domain项目,这意味着我无法让Domain项目看到Utility项目的ToSlug()方法而不会导致循环引用。

我并不热衷于创建另一个项目来解决这个问题,我真的希望保持Slug逻辑的共享。

我怎么解决这个问题?

引用MyCompany.MyProject.Domain Utility项目看起来有点像代码味道。 我假设这些是专门用于域对象的实用程序 – 如果是这种情况,那么为什么不在Domain项目中包含MyCompany.MyProject.Utilities (当然,相应地修改名称空间)?

在任何情况下,打破这些依赖关系的常规方法是将一个项目所需的内容抽象为一组接口,并将它们封装在单独的程序集中。 在此之前,请确保您在概念上做的事情是正确的。

但是,在您的特定情况下,请考虑引入一个接口,即INameHolder

 public interface INameHolder { string FirstName { get; set; } string LastName { get; set; } } 

然后Contact实现INameHolderINameHolder存在于另一个程序INameHolder ,我们称之为MyCompany.MyProject.Domain.Interfaces

然后你的Utilities项目引用Interfaces而不是 Domain ), Domain也是如此,但Interfaces没有引用任何东西 – 循环引用被破坏。

将ToSlug方法复制到Domain项目和Delegate Utility的ToSlug调用此新方法

如果你不能共享域(可能是正确的)并且必须使用共享库中的逻辑,那么你真的必须引入另一个程序集。

或者,您可以通过域中的reflection在域中的运行时加载逻辑以访问依赖库。 它不难打破编译时检查。

如果您确定将代码保存在实用程序DLL中(Eric的答案对我来说似乎很聪明),那么您可以在实用程序项目中创建一个接口,将该接口作为参数传递给ToSlug方法,然后让您的域对象实现界面。