A system can be divided in many ways depending on its size. I’d say projects can be well defined by partitioning them into systems, sub systems, modules, sub modules, layers, packages and components. From the zero day of a project, the management/business team should realize what features the system must have and how many modules are required (i.e. software requirements / usage scenarios).
Then Architects come into play. They define 100% of the layers and 20% of the packages in the same manner Technical Leads/Software Designers define the remaining 80% of the packages and the candidate components. Components (and the sub-X stuff) are not a must. They’re optional. Not all projects need components. Let’s talk the same language: a component is a special type of package with well-defined inputs/outputs, encapsulated, easy to distribute, replaceable and well documented. This jargon explicitly excludes buzz words terms like macro components (can you imagine macro classes? or even macro-bugs?).
It sounds good but, do you really know what it means “easy distribution”? Actually it means internal deployment (for your development teams) and operations friendly neighboring. This makes sense in big development teams. If you haven’t reached 1 million customers for at least, it would be hard to understand it. Only when developing AND supporting Large and Extra Large apps you know what easy distribution means.
So let’s focus on internal deployment e.g.: apps of many product lines have to consume cloud services so it’s a good idea to develop and maintain a layer for accessing them. This layer can contain three packages: the first one is for defining common interfaces/abstractions and some Factories to encapsulate and hide the objects’ initialization. Defining/developing this common package is the 20% of the job which serve as the basis for the 80% of the development. That’s the Software Designer’s job!
The second and third packages are specific implementations of particular cloud services within the layer; let’s say a Visual C# project for Amazon and another one for Azure. Here you’re half down the road; the other half is about distribute it among the development teams. If you think delivering three *.DLLS for each project of your cloud framework is fine, keep reading. Forcing your consumers add multiple *.DLLS for using only the common’s abstractions/facades sucks. Period. The chaos monkey will start mixing and using out dated versions. To be considered a component your packages must be deployed within one DLL.
So what’s the deal?, how to do that? Tooling and language syntax are the easiest parts. Anyone can execute a designing tool. In fact, one million monkeys could eventually come up with a good design according to Jesse Anderson’s findings, but only few would know the rationale behind it.
To achieve easy distribution and well defined inputs/outputs by design start thinking about which classes are for internal use only and use the appropriate class access modifier (you know: private, public, protected, internal protected and internal). Then name your namespaces consistently to group packages within the layer. If your team’s code contains only the public and private keywords get worried.
Finally merge your three .Net modules in one. If you own the full code you can compile against the C# or VB compiler directly to get one DLL from 3 .Net modules. Otherwise download ILMerge from Microsoft, learn to use it, see how others integrate it and start simplifying your internal distribution process. The following line instructs ILMerge to merge/group/embed A.dll and B.dll into C.dll.
C:\Users\SoftwareDesigner>ilmerge /target:library /out:C.dll A.dll B.dll
To see the result open ildasm.exe from the Visual Studio tools console and drag and drop the DLL into it.
Javier Andrés Cáceres AlvisMicrosoft Most Valuable Professional – MVP Intel Black Belt Software Developer