14

我有以下情况:

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

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

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

  4. 问题:我的Utility项目已经在引用我的Domain项目,这意味着我无法在不引起循环引用的情况下让Domain项目看到Utility项目的方法。ToSlug()

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

我该如何解决这个问题?

4

4 回答 4

16

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

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

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

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

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

然后您的Utilities项目引用Interfaces( not Domain ) Domain,但Interfaces不引用任何内容 - 循环引用已损坏。

于 2009-08-23T09:20:42.517 回答
2

将 ToSlug 方法复制到域项目并将委托实用程序的 ToSlug 调用复制到此新方法

于 2009-08-23T09:17:32.930 回答
2

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

或者您可以在域中通过反射在域中加载逻辑以访问依赖库。只是破坏编译时检查并不难。

于 2009-08-23T09:21:21.453 回答
2

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

于 2009-08-23T09:35:21.147 回答