Monday, August 12, 2013

Package principles - .net namespaces and assemblies design guidelines

How to package classes into logical groups and physical containers is always a difficult thing to decide in software engineering. Package is used as it is in Java but when it comes to .Net world, its assemblies. In .Net , the .net framework is packaged in such a way that the core classes and interfaces are packed in one assembly and framework details are in different assemblies. In such a scenario one namespace may appear in multiple assemblies. the namespace in core assembly contains base classes and interfaces where the same namespace in different or track assemblies contain implementations.

Basically we can package by feature or package by layer. In an address book application, if we follow package by feature,  add,edit, delete operation related classes ie CRUD classes will be in a single assembly and the reporting related classes will reside in different assembly. There will be 2 data access classes one for add, edit operations which falls to first assembly and another for accessing reporting related data access falls to second assembly.

Package by layer scenario ie horizontal packaging, package all the UI classes to one assembly, business logic to another assembly and data access classes to third assembly.

My recommendations on .Net assembly packaging

To be frank these are my observations on how to group classes into namespaces and how to split namespaces into assemblies. I didn't get any concrete answer from google on this topic. All were discussing about merits and demerits of different approaches and asking the developer to decide one method. So this recommendations are subject to change as my experience grows.
  • General
    • Follow the other design best practices such as SOLID, GOF patterns properly.
    • Keep in mind that software is created to change in next version.
    • Always group the classes into namespaces which are logical groups.
    • Give meaningful names to namespaces and assemblies. Reading a 100 page document about namespaces and its descriptions may not be practical when project grows more than 100 developers and 75% of them are freshers.
    • A bad assembly dependency graph is as wrong as bad code.
  • Small apps - team size below 10 and working in same location
    • Never go for multiple assemblies but must have different namespaces.
    • Separate creation of classes to factories.
    • When you feel you app is growing beyond initial estimated side create new assemblies as follows.
  •  Medium size apps - team size 10 - 30 and working in same location.
    • Aim should be less no of assemblies so that the application will be fast.
    • If you feel that you may need to support getting a different presentation technology separate the UI namespace into a different assembly
    • Keep your core classes and interfaces in single assembly.
    • Have the default implementations in different assembly where the namespace will be same for the core and its default implementation.
    • One assembly can contain multiple namespaces.
    • eg: format used below is assemblyname{namespaces}
      • AddressBookCore.dll{Joymons.AddressBook.BL,Joymons.AddressBook.DL} - contains interfaces and base classes
      • AddressBookDefault.dll{Joymons.AddressBook.BL,Joymons.AddressBook.DL} - contains concrete implemenations
      • AddressBookUI.dll{Joymons.AddressBook.UI} - implemenations and UI technology specific classes like value converter classes in WPF.
    • Have the additional implementations in different assemblies.
      • If the default data access is through SQL Server and if we want to give XML data storage support, have xml data access class in a separate assembly and change the dependency creation. AddressBookXMLData.dll{Joymons.AddressBook.DL}
  • Big applications - team size more than 30 or working from remote locations.
    • Aim should be to have maximum isolation.
    • Let each track in the application have its on core for business and data access along with  default implementations for all.
    • One assembly should contain one namespace. Name of the assembly should be same as the namespace.

Principles

Like other software engineering principles such as SOLID principle, packaging has also got principles. This will help the developers to package their classes to assemblies in a better way.

http://en.wikipedia.org/wiki/Package_Principles

No comments: