Talking in terms of physical assemblies, infrastructure assemblies (assemblies which contain code that addresses a problem [usually] utilizing a specific framework) shouldn't reference each other directly. Instead you should aim to (at least in my experience) extract an interface from those assemblies and place them into a separate assembly which other infrastructure assemblies can reference. Using your (approximate) situation as an example, you could do something like this:
Things to note:
- All of the boxes represent actual assemblies (projects in Visual Studio).
- Green boxes represent interface assemblies, whereas red boxes represent infrastructure assemblies.
- Interface assemblies contain abstract classes, interfaces, constants etc. They provide abstractions for infrastructure assemblies to use.
- Infrastructure assemblies contain framework-specific code and implement the abstractions contained in the referenced interface assemblies.
- The bootstrapper isn't necessarily required, you can just put the initialization logic in your
Global.asax
. - During the WCF Service's starup process, Dependency Resolution is invoked which registers type mappings.
- Each assembly has their own test assembly (if required).
- This design prevents circular references between assemblies "in the same layer".
- You can easily replace Google Maps with Bing Maps and Entity Framework with NHibernate. The only references that change are in Dependency Resolution.
Let me know if you need further information.