MEF Creating Many Projects

Mar 19, 2009 at 5:39 PM
One of my reviewers commented on the large number of assmeblies in my solution. He pointed out several articles including this and this which describe many projects as anti-patterns.

A solution is a grab bag of what you want to see together (and possibly should exist for each developer based on their tastes). But, the system I'm implementing does have a lot of projects.It feels like this is intrinsic to a composable system. Thus, I wanted thoughts from the MEF-ish. So, I've annotated the project list for comment. I know this will make limited sense without context, but the overall picture of a lot of assemblies (18) wll be clear.

The main bullet items are solution folders, the minor bullets are project names.

·         Common Support

o   Common

o   CommonElements

These two assemblies are separate because CommonElements has a dependency on CommonContracts, and CommonContracts has a dependency on Common. This contains utility stuff that is directly referenced by many projects.


·         Common Interfaces

o   CommonContracts

Contracts (interfaces) used by the core system. This assembly (not others of this group) have direct refs from template harness

o   CommonDatabaseContracts

Contracts to define one large category of metadata that may or may not be used in a given template/scenario

o   CommonDomainContracts

Contracts to define one large category of metadata that may or may not be used in a given template/scenario

o   CommonNamingServiceContracts

Optional contracts for a naming service which may or may not be used in a given template/scenario

o   CommonOutputServiceContracts

Optional contracts for a output service which may or may not be used in a given template/scenario

o   CommonServiceContracts

Miscellaneous contracts which may or may not be used in a given template/scenario

·         Defaults

o   DefaultDatabaseMetadataServices

o   DefaultDomainMetadataServices

o   DefaultOutputServices

o   DefaultServices

These four assemblies above parallel their contract assemblies

o   SemanticHashCondense

This assembly might be combined with the DefaultOutputServices (requiring it to change to C# but I don’t think its currently using VB specific stuff).

o   T4TemplateHost

o   T4TemplateSupport

T4TemplateHost has historically been C#, and T4TemplateSupport uses VB9 XML literals for a key task (the assemblies purpose).

·         Templates

o   DefaultT4Services

Contains the wrapper which allows T4 to play in the MEF space. This and the T4TemplateHost would be implemented independently and hooked via MEF. Combining in the same assembly would make it difficult to control inappropriate intimacy

·         User Interfaces

o   GraphicalUI

o   CommandLineUI

Mar 20, 2009 at 6:40 AM
Edited Mar 20, 2009 at 6:42 AM
Can you not merge the CommonXxxxContract assemblies into one? And then also merge the DefaultXxxx into one assembly? The rest makes sense to me although I would probably not use as many solutions. I usually try to stick to a Framework (solution) and the Application (solution).

You have created assemblies (Projects) to logically divide your source code. You could also try to view an assembly as a deployment unit and structure your code that way - put everything in one assembly that is typically used and deployed together.

Hope it helps.
Mar 20, 2009 at 11:48 AM
I guess we talked about this a bit in one of the earlier threads Kathleen, that it's a deployment issue.  Since an addin system implicitly deals with supporting seperate deployment, I think you're right that larger numbers of projects is an intrinsic element of addin systems such as MEF.

The value judgement you have to make here though is exactly how you want to package your contracts, because it does have versioning issues.  Without deep knowledge of your project, I think only you will be able to make a reasonable call on that.

The 'default' projects would seem to be an easier call - since these don't have versioning issues you can safely package them all as one, and can break it up later if need be.

I've had similar issues where I've ended up with a number of contract assemblies, maybe a few more than I might like, but so far I've stayed with that because it seemed to make sense in my case.

I read the two articles you linked to, and they seem reasonable enough, but any guideline taken to extremes to me becomes an anti-pattern!

I'm joking of course, but what I'm referring to is that the blind application of a guideline becomes a 'rule', not a guideline.  To me, this could well be the case here - there are reasons for limiting the number of projects, but they shouldn't be applied without consideration of other tradeoffs you are making.  It's the balancing act of engineering.  You may very well have good reasons for splitting your contracts into seperate projects irrespective of a colleague pointing towards some article that point out disadvantages.


May 5, 2009 at 8:04 PM
I am currently working on a WPF/Prism/Astoria/Entity Framework/WCF <deep breath> project in a single solution with both client and server side projects included.  There are 32 projects altogether so 18 doesn't sound like a lot.  About half of these are composable modules of functionality that couldn't be combined and still be in line with the composable/plug-in nature of the application. 

Then there is a library project with common client-side stuff as well as a common project for things that are shared between the client and the server side.  One project each for the Entity Framework model, the database itself, the Astoria server-side service, the WCF service, and a client-side service agent to wrap up the two web services.  They add up quickly.

I totally agree with obiwan's and Phil's advice above.  The Common Interfaces seemed like a bit of over-kill as did the separate defaults projects but as the others have stated, without knowing the details, it's hard to judge.

Dave Totzke.