2009-08-23 56 views
10

我有以下情况:循环引用项目

  1. 其中包含我的域模型,以及部分类(如Contact)一个项目MyCompany.MyProject.Domain

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

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

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

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

我该如何解决这个问题?

+1

Slug是一个合适的名字吗?介意扩展使用该名称的理由?这是什么意思? – 2009-08-23 09:35:59

+0

这个问题的URL中的'circular-reference-problem-c'部分(http://stackoverflow.com/questions/1318123/circular-reference-problem-c)被称为slu。。它基本上是用于在引用Web应用程序中的实体/端点的URL中指定(通常是人类可读的)部分的技术术语。主要用于搜索引擎优化或使URL看起来更好。 – Alex 2009-08-23 09:38:01

+0

好....在这种情况下,不应该'Utility.ToSlug()'工作在像'ISluggable'这样的东西上? – 2009-08-23 09:41:48

回答

13

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

在任何情况下,打破这些类型依赖的正常方法是将一个项目所需的内容抽象为一组接口,然后将这些接口封装在单独的程序集中。在做这件事之前,请确保你在做什么在概念上是正确的。

在您的具体情况,但,考虑引入一个接口,即,INameHolder

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

然后Contact实现INameHolderINameHolder存在于另一个组件中,我们将其称为MyCompany.MyProject.Domain.Interfaces

然后你Utilities项目引用InterfacesDomain)也是如此Domain,但Interfaces不引用任何东西 - 循环引用被打破。

+0

我可能会用这个....现在试验。 – Alex 2009-08-23 09:38:38

2

副本ToSlug法域项目,并委托实用的ToSlug调用这种新方法

+0

'委托实用程序的ToSlug调用这个新方法' - 请澄清?怎么样? – Alex 2009-08-23 09:18:49

+0

这也是我最初的想法 - 但我认为域没有共享,因此不允许加载扩展库。我本来可能是错的。 – 2009-08-23 09:28:18

2

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

或者您可以通过域中的反射来加载域中的运行时逻辑以访问相关的库。它并不难,只是打破了编译时间检查。

2

如果你确定关于保持在实用DLL的代码(Eric的答案似乎聪明给我),那么你可以创建在您的公用事业项目的接口,通过该接口作为参数传递给您的ToSlug方法,然后让你的域对象实现接口。