If you want to decouple your abstractions from their implementations (always a worthy goal), you should define those abstractions in their own assembly From the implementation side, this is easy to deal with, becuase you need to reference the abstractions to implement them. There's no way around that whether you use MEF or not, so that's as it has always been: Import(typeof(IFoo)) public class MyFoo : IFoo { } However, as you say, this means that you can't reference your Composition Root from the abstraction library. However, that is as it should be, because the abstractions shouldn't worry about how they get composed In other words, you must implement the composition of the dependencies outside of the abstraction library.
A good candidate for that is the executable itself, whereas you would keep all your concrete implementations in one or separate libraries The abstraction library will have no references, while both consumers and implementers would need to reference it, so a dependency graph might look like this: Composition Root --> Abstractions.
If you want to decouple your abstractions from their implementations (always a worthy goal), you should define those abstractions in their own assembly. From the implementation side, this is easy to deal with, becuase you need to reference the abstractions to implement them. There's no way around that whether you use MEF or not, so that's as it has always been: Import(typeof(IFoo)) public class MyFoo : IFoo { } However, as you say, this means that you can't reference your Composition Root from the abstraction library.
However, that is as it should be, because the abstractions shouldn't worry about how they get composed. In other words, you must implement the composition of the dependencies outside of the abstraction library. A good candidate for that is the executable itself, whereas you would keep all your concrete implementations in one or separate libraries.
The abstraction library will have no references, while both consumers and implementers would need to reference it, so a dependency graph might look like this: Composition Root --> Abstractions.
Can't reference your Composition Root from the abstraction library" - That's the goal, but also the source of my confusion. If my abstractions have a property of type "Engine", which is defined and implemented in my implementation library, do I need to create an interface "IEngine" for this type in the abstraction library too? Now, if I have multiple types in need to reference, each again with their own dependencies, I'd need to abstract all of those into the abstraction library, wouldn't I?
– Michael Wagner Mar 2 '10 at 11:16 2 Yes, that is correct. All those extra interfaces may seem like a lot over overhead, but each is actually a Seam where you decouple implementer from consumer. The end result is a looser coupled system.
The benefit may not be immediately obvious, but once you begin to experience the power of consuming and exposing abstractions instead of concrete types, you will never want to go back :) – Mark Seemann Mar 2 '10 at 11:20 thanks, so what I thought was too much, is actually perfectly fine and needed! – Michael Wagner Mar 2 '10 at 11:30 Yes, exactly :) – Mark Seemann Mar 2 '10 at 12:08 amen - once I discovered the secrets of abstractions and interfaces, I use them all over the place. – IAbstract Mar 2 '107 at 0:43.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.