Circular references, interfaces, and project layout RRS feed

  • Question

  • (hopefully this isn't duplicated; I've had problems posting)


    I've been sidestepping this issue for a while since I don't really have any way of handling this that I've been particularly happy with. Here's what I'm trying to understand/handle:


    Occasionally I'll run into a circular reference issue (a type declared in project X depends on a type in project Y. Project Y depends on project X). Depending on the circumstances, one way to handle this is to move common code out into another project and reference that instead. As part of this, you might also create an interface instead of the explicit type.


    I've been following the project naming convention that the project matches the primary namespace (ex. the project might be named MyCompany.Utility). Subfolders in the project also follow the namespace (so a folder named "Encryption" in the MyCompany.Utility project would be in the namespace MyCompany.Utility.Encryption). That seems to work OK for me.


    Now here's the scenario I've run into. I want to define a base / abstract type. This type implements an interface which should expose a single method, and an event. If I create the interface in the same project as the class which implements it, all is well. However, if I decide I'd like to move it out to another project (maybe MyCompany.Interfaces) I also need to either move or reference the types that the interface depends on. If I move them, I then end up with types in MyCompany.Interfaces which aren't actually in the MyCompany.Interfaces namespace (since I still would like them to appear in their original namespace). This is a bit ugly (I've done things like just create a folder with the full namespace that they really appear in under this project, ex. a folder named MyCompany.Utility).  If I just reference the other assembly, I'm just setting myself up for circular reference issues.


    How are other people dealing with these issues?

    Thursday, October 4, 2007 5:26 PM

All replies

  • Hi Paul

    You should only create a new project to get another assembly, the only reason you want code in a different assembly is for deployment so you can deploy it somewhere else otherwise just use namespacing.

    So for example your utility classes may be used accross several projects so package them up in their own project. Probably solution in ths case too.

    Your interface project should only exist as a seperate project if you have a boundary and you need the interface classes referenced by two seperate applications (or tiers in a distributed application). If this is the case then it and it's dependant classes would be an interface and some data transfer object classes which are unlikely to further reference anything else (apart from your utility project most likely).

    Typically you only end up with circular reference problems like you described where people have not followed this and added projects to logically seperate code in their application instead of using namespaces properly.

    I've seen a solution where the number of projects reached 3 digits and part of that was because once you get that many proejcts you are going to run into circular references and people will have to create an extra project as you described to get around it each time and it spirals out of control.

    Hope this helps

    Thursday, October 4, 2007 6:53 PM
  • You can extract the interface on the concrete type and then the interface classes can reference other interfaces, not concrete types.



    Friday, October 5, 2007 2:27 AM