Separation of Concerns is a design principle which states that distinct parts of a software system should be separated and should not overlap in terms of features and functionality.
In technical terms this can be achieved by grouping common functionality into separate projects but that in itself is not enough, any hard reference to other projects that violate the separation of concerns should be avoided and this can be tested and enforced using an integration test.
As an example in the sample solution below we have four projects. to truly have separated concerns in the following solution the presentation layer should only reference the domain services layer and it should not have any hard references to the data access layer.
In order to write a unit test to test for hard references from the presentation layer to the data access layer we can create a unit test project and write the following test:
[TestMethod]
public void ShouldNotAccessDataAccessLayerDirectly() {
Type webRepresentative = typeof(HomeController);
Type dataAccessRepresentative = typeof(BaseRepository);
var references = webRepresentative.Assembly.GetReferencedAssemblies();
AssemblyName webAssemblyName = webRepresentative.Assembly.GetName();
AssemblyName unwantedReferenceAssemblyName = dataAccessRepresentative.Assembly.GetName();
Assert.IsFalse(
references.Any(a = > AssemblyName.ReferenceMatchesDefinition(unwantedReferenceAssemblyName, a)),
string.Format("{0} should not be referenced by {1}",
unwantedReferenceAssemblyName, webAssemblyName));
}