This is the 2nd part of our forkwind implementation. If you are not aware of the master thread and forkwind, please go here first.
In this article, I'll briefly dig modularity and how it maps into .NET assemblies. Modularity is simply dividing our applications into smaller modules. The benefits are obvious: Debugging is easer, and multiple people in the team can work in different modules without affecting each other. Finally, modules are rather isolated so further modifications can be made to one module without breaking the system. This provides us good maintainability for a particular project.
In .NET world, our assemblies act as modules (formally, a module is a code file in .NET but we will ignore this fact to prevent confusion). Each project we create in Visual Studio corresponds to an assembly. It can be a dll or it can be an exe. Even for a web application (and not for a website!) all we get is a dll along with some aspx files. .Net assemblies also provide us additional benefits like versioning, security and ease of deployment.
Assemblies in Forkwind:
In Forkwind, in Part 1 as you remember we have generated several projects/assemblies. This may seem natural to you since we have a layers: a gui layer , a test layer etc. But why did we create separate projects ? It is technically possible that we could have created a web application project and we could build all our code right into that (and even including unit testing). Is it to reduce the pain of an environment with multiple developers ? Certainly not. If you read above my informal definition to modularity, you will understand the reason. We are looking for good design! And good design dictates us building our application in modules. In some case it is perfectly valid to have a single assembly and in some cases using multiple assemblies can be overkill. Only experience can tell when to use what.
Specifically talking on .NET my rule of thumb is if I expect a layer to be replaceable with another equivalent code, I create an assembly for that. So my repository implementation might change in the future , thus I create an assembly for that particular layer. If not I would lean towards a more monolithic design. Is this my only criteria no ? For a plug-in like system again you have to create assemblies so that you can load them on runtime without stopping your main executable. Finally an assembly like Forkwind.Test should be seperate. Because it doesn't belong to code. It is ony useful for testing. It has no business within the production environment to create excessive code. So for optional components again I create an assembly. Finally when there are issues of versioning, or a different security setting is concerned I create an assembly for that again. The rest really depends on your taste.
What about namespaces ?
From time to time, I see some novice developers are confused about a namespace and the assembly name. This is due to mainly relying on Visual Studio's intellisense. Namespaces and assemblies has nothing to do with each other actually. They are apples and oranges. A namespace's solely purpose is to prevent Class name clashes. It is NAME-SPACE ! An assembly is more like a module. And just because you can use a namespace like System.Configuration appears with intellisense in Visual studio, it doesn't mean that you are actually making use of the System.Configuration assembly. In deed, all you see is the System.Configuration namespace within System assembly!
One exception to this , namespaces have another use in C# 3.0 which allows resolution for extension methods.
So that's it for part 2. No new code in this part. But we will get our hand very dirty in next part:
* Forkwind Part 3: Creating the domain model