views:

106

answers:

3

Please describe the .NET assembly compilation circular dependency problem in layman's terms, and whether other technologes have similar limitations.

Note: This seems like a simple question, I know, but I have seen a number of real, significant projects that have totally broken dependency graphs.

+3  A: 

Same as any other circular dependency...

Consider three assemblies A, B & C

A needs something defined in B, B needs something defined in C, and C needs something defined in A.

Which can you build first?

BioBuckyBall
You don't even need three - just A needs something in B and B needs something in A.
Will Dean
True enough. I used three because two doesn't 'feel' circular, more like 'ping pong dependency' :)
BioBuckyBall
Would it be possible to compile into an intermediate meta-assembly for splitting according to project right at the end of the compilation process?
Ben Aston
@Ben Aston - It may be, but much better (IMO) would be to move things such that you don't have the circular dependency anymore. If you add some details maybe we can help you with that (or ask it in a new question).
BioBuckyBall
@Lucas, thanks. I am thinking hypothetically. I am interested in exploring to what extent the circular dependency limitation between assemblies in VS is artificial vs real.
Ben Aston
@Ben Aston - Good deal. In that case, it might be instructive for you to try and make a circular dependency in a little throw away project and then refactor it out.
BioBuckyBall
@Lucas - I have created said project and played with programmatic circular dependencies too. It just seemed that the circular dependency dialog in VS is merely using the simple heuristic of "A refs B, so B cannot ref A", as opposed to examining the code to see if an issue really exists - or whether it would even be possible to implement a compiler in such a fashion as to attempt compilation using my aforementioned intermediate compilation step.
Ben Aston
+2  A: 

To add to Lucas's answer: it's very hard to come up with a circular assembly dependency in .NET. In order to compile A.dll you first need B.dll; to compile B.dll you first need C.dll; but to compile C.dll you need the A.dll you were trying to compile in the first place.

The only way you're likely to get into this situation is if you're developing A, B and C in parallel, and you've managed to introduce a circular dependency by accident. But as soon as you do a clean build of all three, the problem will be apparent, and you won't be able to proceed until you break the cycle.

Circular dependencies between namespaces and/or classes within a single dependency are a lot more common. I try to treat this kind of circular dependency as a code smell; a codebase without circular dependencies between components is one where those components can easily be kept separate and refactored independently.

Patrick Smacchia (the NDepend guy) talks a little about dependency cycles and their effect on code quality here: http://codebetter.com/blogs/patricksmacchia/archive/2009/07/29/maintainability-learnability-component-layering.aspx

Tim Robinson
A: 

There are 2 things here:

1) do you consider assemblies as component? You should not, I explain my stance here: Advices on partitioning code through .NET assemblies

2) whatever you consider as a component, cycles amongst components are harmful, I explain my stance here: (Section: Why are dependency cycles harmful ?) Control component dependencies to gain clear architecture

Patrick Smacchia - NDepend dev