I have a medium-sized project, which implements about 20 or so different concepts. At the beginning, I chose to organize my assemblies based on conceptual layers, like so:
MyProject.Domain.dll (References System.Data.Linq, etc.)
\ConceptA\
\ConceptB\
\ConceptC\
\...\
MyProject.Presentation.dll
\ConceptA\
\ConceptB\
\ConceptC\
\...\
MyProject.WinForms.dll (References System.Windows.Forms, etc.)
\ConceptA\
\ConceptB\
\ConceptC\
\...\
MyProject.App.exe (References all the above)
I've recently read in a DDD book that I should group my assemblies based on the domain concept it represents, rather than the technology layer, like so:
MyProject.ConceptA.dll (References System.Data.Linq, System.Windows.Forms, etc.)
\Domain\
\Presentation\
\WinForms\
MyProject.ConceptB.dll
\Domain\
\Presentation\
\WinForms\
MyProject.ConceptC.dll
\Domain\
\Presentation\
\WinForms\
MyProject.App.exe (References all the above)
I don't have enough experience to judge the two approaches in the long term. I want to strike the best balance between complexity and flexibility. I have a few concerns that make me feel ambivalent:
MessageBox.Show
from my domain layer.In your experience, which is the best approach?
TL;DR: You should be doing both, but don't split your project up into multiple assemblies just for the sake of it. By splitting your assemblies down to reusable components you will end up using a combination of both methods where appropriate.
Firstly, I'd say that depending on the size of your project there may not be any need to separate either concepts or layers our into separate assemblies - the advantages of separating out your code into separate assemblies is twofold:
If you don't have any need for either of those two (and you wont in the future) then keep your life simple and just bung everything into one assembly.
Secondly, the primary reason for separating code out into separate assemblies is to re-use that code - for example if you have a piece of processing logic being used in a Windows Forms application, separating that out into a separate assembly lets you re-use that logic in say a console or web application. For this reason I usually find that the best way is to separate on concepts, for example:
Company.Project.Concept.dll
Where "Concept" is something that you want to re-use, be it a set of common Windows controls or some data access logic.
Note that when re-using a concept its fairly rare to want to re-use all conceptual layers of that concept (Domain / Presentation / WinForms). Normally either your concept only consists of 1 layer (e.g. some form of processing), or when re-using that concept you are only interested in 1 or possibly 2 layers. In this case if your "Concept" assemblies also contain other extra logic (such as WinForms) you are just referencing extra code that will never be used. For this reason its also normal to separate out into conceptual layers if you have them, for example:
Company.Project.Concept.Processing.dll
Company.Project.Concept.WinForms.dll
I.e. in the example you gave I'm advocating that if anything you would want 9 assemblies, not 3:
MyProject.ConceptA.Domain.dll
MyProject.ConceptA.Presentation.dll
MyProject.ConceptA.WinForms.dll
Of course splitting your project down into hundereds of assemblies is completely pointless unless these individual concepts are actually going to be used elsewhere which brings me back to my first point - don't bother splitting up assemblies unless you actually need to, or to put it another way split your assemblies up into the re-usable components that make sense:
As a working example I automatically opt to split smaller projects into two assemblies - the application itself which contains all the "presentation" (be it Web, WinForms, WPF or a Console app), and another assembly which contains the "meat" of the application - the underlying functionality being exposed by your application (e.g. image processing, data retrieval etc...). This helps if I ever want to expose the same functionality in a different style of application.
Once more though I would err on the side of too few assemblies rather than too many - its easier to split an assembly in two than it is to combine two assemblies back into one. Unless you can find a compelling reason to split an assembly / project up into multiple assemblies, don't bother.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With