Contract vs. implementation assemblies - KirillOsenkov/Bliki GitHub Wiki

There's an informal pattern used by several products at Microsoft to organize assemblies in predominantly contracts (Definitions) and Implementations. There are several benefits, such that you have consumers mostly referencing the contracts assemblies and are more free to change the implementation.

Another benefit is flattening the build graph. If you directly reference an implementation assembly, you have to rebuild your assembly every time it changes (which is presumably often). If you instead reference the contract assembly, it doesn't change nearly as often, and this lets you avoid rebuilding your projects unnecessarily.

Examples of Definitions/Implementations split:

  1. Visual Studio Editor - at authoring time, the implementation for each feature is in its own *.Implementation.dll however at deployment time all Implementation.dll assemblies are merged into a single Microsoft.VisualStudio.Platform.VSEditor.dll via a consolidation process (which could be ILMerge/ILRepack, or having a single giant .csproj which includes all the .cs files from all implementations)

  2. MSBuild - Microsoft.Build.Framework.dll is an example of a contracts assembly with primarily interface and type definitions. The bulk of the implementation goes into Microsoft.Build.dll which depends on the Framework.dll

  3. CPS - Microsoft.VisualStudio.ProjectSystem.Implementation.dll is the implementation details, Microsoft.VisualStudio.ProjectSystem.dll is more of a contracts assembly, however the separation is not as strict here.

Notably, Roslyn doesn't use the Def/Impl split, but I can't remember the reasons.