The Dependency Inversion Principle is this wonderfully clever concept for decoupling layers. I've written a bit about it before here.
To summarize, the idea is that your high layers define interfaces that your low layers implement. Thus insulating the high layer from the low layer. This fits in very nicely with TDD as you can write/test the high layers first and mock out the low layers.
So DIP is good stuff. But it doesn't play well with reusable component architectures. That is, if you're designing software components which you intend to use in many different places (some of which may be as yet unknown), you can't use DIP between them.
Maybe it's time for an example. Suppose we have a Component A and a Component B. Now we're writing a third Component C which will use A and B. Finally, we have an Application App which will use A, B, and C.
A, B, and C may all use DIP to structure the layers within the components. But you wouldn't want to use DIP between the components. If we tried to do that, we would have to define two interfaces in C that described how it used A and B. And three more interfaces in App that described how it used C, B, and A. Then A and B would both have to implement interfaces defined in C and App. Plus C would have to implement interfaces defined in App. And now you can't reuse A, B, or C in another App (without including App).
So what do we do if we want our COMPONENTS to be independent, just like our layers? Just change it slightly. Create an assembly for each component that contains interfaces used to interact with the component (ex: A.Contracts). Make A implement these interfaces, and let anyone who wants to use the component reference the Contracts assembly.
If you have another approach, or a similar issue, or you know, stuff to talk about... Let me hear it.