Say I have BusinessService
& domain logic as part of MyProj.MiddleTier
csproj which connects to MyProj.DAL
DataRepository
via interface IDataRepository
.
I am using IOC unity container to build my dependency object graph. Composition root and BusinessService
are all part of MyProj.MiddleTier
(BusinessService
is WCF based service consumed from WEB server and I have overridden ConfigureContainer
method to build object dependency graph using my own serviceHostFactory
)
I would like to understand shouldn’t IDataRepository
be part of separate csproj (assembly) ? In fact shouldn’t be composition root itself be separate project/assembly holding reference of all assemblies ? If not, then I feel whole purpose of DI is defeated. Why ? Because if MyProj.MiddleTier
has hard dependency reference of MyProj.DAL
then I cannot simply switch to another persistence technology tomorrow without recompiling MyProj.MiddleTier
. Had been MyProj.DAL
just referenced that IDataRepository
in separate assembly, it would have required to just deploy MyProj.DAL dll
.
Also by not having it as part of separate assembly, developers can accidentally directly reference to classes and implementation of DataRepository
in Business/Domain logic. Is this well known trade off ? If yes, then what are merits ?
In stack overflow I see mix of response :
This post on SO says actually there is no harm in doing so however another post says its good to have separate assembly.
Irrespective of above mixed SO answers, I was holding good belief on my thought process until I bumped upon similar text from famous book “Dependency Injection in .Net”. Here example taken is of ASP.NET MVC project where UI layer and composition root for building object graphs are part of same assembly.
However author also provided some explanation for this :
Don’t be misled into thinking that the Composition Root is part of your UI layer. Even if you place the Composition Root in the same assembly as your UI layer, the Composition Root isn’t part of that layer. Assemblies are a deployment artifact: you split code into multiple assemblies to allow code to be deployed separately. An architectural layer, on the other hand, is a logical artifact: you can group multiple logical artifacts in a single deployment artifact. Even though the assembly that holds both the Composition Root and the UI layer depends on all other modules in the system, the UI layer itself doesn’t
I think the core of my confusion is because of not understanding point around deployment artifact and logical artifact. I would be great if someone can help me understand this better.