Tuesday, June 17, 2008

Forkwind: Part 2: Modularity, .NET Assembly and Namespaces

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

Stay tuned!!!


bryan said...

Hey Omar,

There's a pretty good relationship between namespaces and assemblies, where the namespace matches the assembly name. This is especially true when the assembly represents a different technology or focus -- Web versus Console.

Assemblies are meant as a packaging mechanism and it's safe to share the same namespace between assemblies. A great example is your Test assembly: Tests shouldn't require special namespaces and we split them off into their own assembly for packaging reasons (code bloat and deployment considerations). I've got a (IMHO) good write-up about Test Namespaces which talks a bit about this..

btw, I'm just joining the discussion at step three, but this is really interesting to watch this unfold. Good stuff.

Onur Gümüş said...

Hello bryan, I agree that usually namespaces and assemblies are correlated.
I've also read blog about your Test Namespaces. Though I am not sure if I get you correctly. How do you name the TestClasses them self ?

For my discussion yeah, I try to go in my natural order as a I develop a project. Thanks for your comment and feed back.

My name is Onur by the way ;-)

Dutt said...

Thanks for this Very nice article. and one more here i found. 5 Parts of .NET assembly tutorial.

.NET Assemblies Tutorial Part 1 of 5 - An Overview of .NET Assemblies

.NET Assemblies Tutorial Part 2 of 5 - Single-File and Multifile Assemblies

.NET Assemblies Tutorial Part 3 of 5 - The Role of the Common Intermediate Language

.NET Assemblies Tutorial Part 4 of 5 - The Role of .NET Type Metadata

.NET Assemblies Tutorial Part 5 of 5 - The Role of the Assembly Manifest