Resolving Circular References (C#)

倾然丶 夕夏残阳落幕 提交于 2019-12-18 05:06:22

问题


I'm having a couple of problems with circular reference/dependency that I've been sitting on all day. Something must be wrong with my thought process, I just don't get it.

Here are my projects:

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

Current References/Dependencies:

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

I wanted to structure my project in a way that my services project has all services, my domain project the model, repository and 'fluent' extensions to query the model, and the main and utility project are pretty much self explanatory.

Problems encountered:

1) I have an EmailService in my Flip.Services project, which needs to send out localized emails. All localization is done in Flip.Main's App_GlobalResources. No idea how to get the strongly typed emails and other localized resources now to my service layer as Flip.Main already depends on the service layer and therefore I can have it depend back to the Main project.

2) I have business classes, e.g. CustomerSearchFilter which represents a strongly typed search query. I want those business classes outside of the Flip.Domain project because they are not part of the domain model. However, in my CustomerSearchFilter class I have domain class instances (e.g. CustomerGroup) so it needs to know about domain classes. At the same time my Fluent interface in my Flip.Domain project needs to know what CustomerSearchFilter is so I can apply it to my IQueryable interface. Circular reference again.

3) I have a custom [AuthorizeSessionState] attribute which I use to decorate specific controller actions in my ASP.NET MVC Flip.Main project. This is an ActionFilterAttribute which needs to instantiate my SessionService who resides in my Flip.Services project. I can't put this into my Utility class though (because Flip.Services already references Flip.Utility). I don't think they should be in Flip.Main either - do I have to make another project for this!?

(20 more)

I feel like I'm making a mistake somewhere down the line, especially when I read that others usually don't encounter circular reference problems. Help?


回答1:


Use interfaces for all non-trivial classes. Place interfaces in a different assembly from implementation.




回答2:


The question comes down to what you separate by namespace and what you separate by DLL. If you have a good reason to keep EVERYTHING modular, you have to work really hard. But if each of these dlls only have a class or two in them, perhaps you could merge them together?




回答3:


Take a few minutes and sort out the procedures ... create an identifier for each project (FM, FS, FD, FU). List each publicly accessible procedure on a page and then add an identifier for a project, if that project uses the procedure ...

Then you can see which procedure needs to be in (or accessible to) which project.

Hope that helps!




回答4:


  1. You can put your localized email strings in Flip.Services. The downside is that you have two places to maintain localized resources. You can also have a separate dll for all your resources to minimize the place to edit resources.
  2. You have to move the fluent interface to an other dll or make CustomerSearchFilter part of the domain.
  3. You will need to add more projects or rearrange your structure and use namespaces to create the separation.



回答5:


It sounds like your building on concrete implementations instead of interfaces/contracts. As Ima suggests define interfaces that describe what a certain class should be able to do. Use this interface when you declare properties, parameters and the like. Keep the interfaces separate from the implementaion and both the implementation and the projects that uses the interface can reference the interface project.

You then get the nice option of using dependency injection making your code easier to test as an a side




回答6:


In the "tiers" of a domain, repositories and services live at the same logical level, above the domain in an infrastructure role. I would suggest moving your repository implementations (queries, etc.) outside of the domain itself. That solves #2 at least.



来源:https://stackoverflow.com/questions/1320561/resolving-circular-references-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!