解决循环引用(C#)

我在循环引用/依赖方面遇到了一些问题,我一整天都在这里。 我的思维过程肯定是错的,我只是不明白。

这是我的项目:

 Flip.Main (ASP.NET MVC) Flip.Domain (C# DLL) Flip.Services (C# DLL) Flip.Utility (C# DLL) 

当前参考/依赖:

 Flip.Main -> Flip.Domain, Flip.Services, Flip.Utility Flip.Services -> Flip.Domain, Flip.Utility Flip.Domain -> Flip.Utility 

我想以我的服务项目拥有所有服务的方式构建我的项目,我的域项目模型,存储库和’流利’扩展来查询模型,主要和实用程序项目几乎是自我解释。

遇到的问题:

1)我的Flip.Services项目中有一个EmailService,需要发送本地化的电子邮件。 所有本地化都在Flip.Main的App_GlobalResources中完成。 不知道如何将强类型电子邮件和其他本地化资源现在提供给我的服务层,因为Flip.Main已经依赖于服务层,因此我可以让它依赖于Main项目。

2)我有业务类,例如CustomerSearchFilter,它代表强类型搜索查询。 我想在Flip.Domain项目之外的那些业务类,因为它们不是域模型的一部分。 但是,在我的CustomerSearchFilter类中,我有域类实例(例如CustomerGroup),因此需要了解域类。 同时我的Flip.Domain项目中的Fluent接口需要知道CustomerSearchFilter是什么,所以我可以将它应用到我的IQueryable接口。 再次循环引用。

3)我有一个自定义[AuthorizeSessionState]属性,我用它来装饰我的ASP.NET MVC Flip.Main项目中的特定控制器动作。 这是一个ActionFilterAttribute,需要实例化驻留在Flip.Services项目中的SessionService。 我不能把它放到我的Utility类中(因为Flip.Services已经引用了Flip.Utility)。 我不认为他们应该在Flip.Main中 – 我是否必须为此制作另一个项目!?

(另外20个)

我觉得我在某个地方犯了一个错误,特别是当我读到别人通常不会遇到循环引用问题时。 救命?

为所有非平凡的类使用接口。 将接口放在与实现不同的程序集中。

问题归结为您按名称空间分隔的内容以及您通过DLL分隔的内容。 如果你有充分的理由保持一切模块化,你必须努力工作。 但是如果这些dll中的每一个只有一两个类,也许你可以将它们合并在一起?

花几分钟时间整理程序……为每个项目(FM,FS,FD,FU)创建一个标识符。 列出页面上的每个可公开访问的过程,然后添加项目的标识符,如果该项目使用该过程…

然后,您可以查看哪个程序需要(或可访问)哪个项目。

希望有所帮助!

  1. 您可以将本地化的电子邮件字符串放在Flip.Services中。 缺点是您有两个位置来维护本地化资源。 您还可以为所有资源使用单独的dll,以最大限度地减少编辑资源的位置。
  2. 您必须将fluent接口移动到其他dll或使CustomerSearchFilter成为域的一部分。
  3. 您需要添加更多项目或重新排列结构并使用命名空间来创建分隔。

这听起来像是建立在具体实现而不是接口/契约上。 正如Ima所建议的那样定义接口来描述某个类应该能够做什么。 声明属性,参数等时使用此接口。 保持接口与实现分离,并且实现和使用该接口的项目都可以引用接口项目。

然后,您可以选择使用依赖项注入,从而使代码更容易作为一方进行测试

在域的“层”中,存储库和服务位于基础结构角色中的域之上的相同逻辑级别。 我建议将您的存储库实现(查询等)移到域外。 这至少解决了#2。