Assembly Partioning Advice

Patrick Smacchia wrote an excellent post on how you should partition your code in multiple assemblies. Because this is one of those subjects that i’m pretty opinionated about, i figured i’d quickly recap the valid and invalid reasons for creating assemblies that Patrick highlighted.

Valid reasons for creating a new assembly:

  • Tier separation: separating the code you will run in different processes. For instance: having an assembly for client-side only stuff, and one for server-side only stuff

  • Avoid premature loading of large pieces of code that aren’t always necessary: if you put the ‘optional’ code in a separate assembly, that assembly won’t be loaded until you actually need it.

  • Framework feature separation: if your framework offers types that will never be used together (for instance: types for web development vs types for windows development) then it doesn’t really make sense to put them in the same assembly.

  • AddIn/Plugin model: there are many valid reasons for putting plugins in their own separate assemblies

  • Tests: i personally don’t like to put my test code next to my production code, so i always put that in a separate assembly

  • Shared types: all ‘common’ types that you would like to use in different tiers

Invalid reasons for creating a new assembly:

  • Assemblies as units of development: there’s not a single source control management system that doesn’t make it easy for multiple people to work on the same assembly

  • Assemblies as units of reusability: this one wasn’t on Patrick’s list, but it is a pet peeve of mine. I’ve often seen people separate things into multiple assemblies so each part could be reused separately. Which is a prime example of Intellectual Masturbation Syndrome if there’s no actual need to reuse each assembly separately.

  • Automatic dependency cycle detection: when assemblies have cyclic dependencies on each other, Visual Studio automatically notifies you of the problem. Patrick obviously recommends using NDepend to prevent such problems. I’d recommend thinking before/during/after you write the code 🙂

  • Using internal visibility to hide implementation details: if you want to hide implementation details you can use the internal access modifier so the ‘internal’ parts are only available to the types contained in the owning assembly. I seriously dislike this approach. Using the internal access modifier is often a good sign that there is something wrong with the design. Hiding implementation details is not always the same thing as ‘proper encapsulation’!

  • Using internal visibility to prevent usage from the rest of the code: Yet another approach that i seriously dislike. I prefer to use the Published vs Public approach

2 thoughts on “Assembly Partioning Advice

  1. Good post.

    People tend to gloss over as being “obvious” only to have it bite them hard later on. In my experience the point where it bites them hardest is during deployment and servicing (e.g. install, patch, uninstall)

    Re: servicing…

    Whether you are using Click Once, MSI or some other mechanism the servicing model can have implications around how the assemblies should be structured.

    For example – a self-updating program. The assembly partioning requirements for a program that downloads it’s own updates and patches itself (while running) are different from a program that is only updated using MSI patching or a program that never needs to be updated.

    Another example for servicing would be whether or not a component were needed during the MSI install/patch/uninstall phase.

    Re: deployment locations…

    Should the assembly go into the GAC or not (that question affects servicing as well)? Should the assembly be deployed with your core application or in a common area (such as a program files common area or in the plug-ins directory of another program you are integrating with)?

    On a related note – I would go further and say that tests never belong in production assemblies. They are just trouble waiting to happen.

  2. On “Assemblies as units of development” and “Assemblies as units of reusability”, I think whats missing here is that when you say assembly we’re actually using projects.

    Projects are the unit of dependency so they are a unit of reusability/development. Obviously with careful use of NDepend you can handle dependencies more granularly e.g. by namespace, but NDepend isn’t for everyone.

    To be honest the main reason against having lots of projects for me is the speed issue which is difficult to workaround.

Comments are closed.

Proudly powered by WordPress | Theme: Code Blog by Crimson Themes.