Organizing Composed Systems

Mar 8, 2009 at 11:17 PM
My system has about 30 interfaces stretched across two assemblies whose process boundaries makes a fair amount of sense.

I have about 30 implementations intially. They are currently stretched across about 4 assemblies.

Is there any guidance written about organizing mid-size to large number of interfaces or implementations.

Are there any casual suggestions anyone would like to make?

Opt for more implementation assemblies for deployment flexibility? What are the driving forces other than how it looks in my Visual Studio Solution Explorer?
Mar 9, 2009 at 2:15 PM
Kathleen, what are your deployment requirements?

Do you need to be able to deploy the implementations seperately?  It does sound like that should probably drive your decisions - sounds like a packaging and deployment consideration.  Personally, if I didn't forsee a need to deploy seperately I would keep it simple - package as a single assembly.

I would be more concerned with how many and which assemblies, the interfaces are packaged into - at the end of the day you should be decoupled from the implementations when using MEF, so this allows you to easily change how you package implementations.  You could start with a single assembly containing all your implementations and then later change your mind - and move them into individual assemblies.  What of course causes much more issues is deciding later that you wished you had packaged interfaces differently.  So, I would tend to focus on that. 


Mar 9, 2009 at 2:26 PM
To throw in an additional comment - one of the main ways I think about assemblies, in addition to considerations of placing related components/functionality within the same assembly, is that assemblys are also your unit of versioning....

So, if I want to be able to version components independently, that may push me towards packaging the components in seperate assemblies.  This pattern applies less when using MEF though (or dependency frameworks) since you typically avoid taking direct dependencies on implementations.  It does however, still apply to the interfaces and the assemblies which contain your interfaces, since you do take dependencies on the interfaces.


Mar 9, 2009 at 3:01 PM

Thank you. Excellent points.

The purpose of the system is to orchestrate the actions of code generation. Becuase of the complexity of the domain (generally overlooked when people start) I would like to start with a set of default implementations for the moving parts (like naming service) that people are quite likely to want to do on their own, but not day one. And it's a true composable system intended to foster and extend a public ecosystem. I will have no control after full launch (I insist on the capacity to backtrack from my initial CTP).

The interfaces question is quite good. Obviously blocking later changes and at present they are far to monolithic in deployment, which I will fix. However, I'm in a domain space where encouraging standards is criticial because it allows metadata, service and template exchange. As such, I think I'll package them in standad sets. Someone can stilll use another interface, but if they want A, and B/C generally make sense with A, I'll package them together.

But even more than that, both parts that will ultimately use the MEF established relationship will need to import the interface. Thus having an overly granular interface deployment is going to be a true pain in the backside (referencing 27 different interfaces (slight exageration)).

The issue that keeps naging me is defaults. I can't get my head around making defaults work the way they are designed within MEF. The major problem I have is that for one scenario (the graphic UI) I must build the container at two points. I build it, then add more catalogs that I don't know about at startup. To use defatults in a full composable ecosystem, every single part has to be in its own assembly (you may want Joe's part A, but Sam's part B, so a design that delivers A/B together won't work). Since there will be dozens to hundreds of parts this seems a total nightmare. But what's worse is that I cannot control how people deploy the parts they build for the ecosystem. Thus, I'm well on my wayt to a prioritization/default system that is under my control and quite granular using strongly typed attributes.

From conversations with Glenn my use of MEF is relatively unusual, although MEF has allowed me to completely rethink a common problem in a really important way. You can hear a bit more about what I do on this week's Hanselminutes.

Thanks again for your comments,
Mar 9, 2009 at 3:32 PM
Sounds very interesting Kathleen - I'll definitely check out your interview.  Hanselminutes is always a good listen.

I'll have to check out the defaults support - I haven't used that, so It'll take a bit for your comments to percolate.  It sounds a bit problematic the way you describe it - doesn't sound desirable that the assembly packaging affects your ability to choose which defaults to use.

So... a side question since it sounds on the surface like you may have similar issues to me, and I'd be interested in your thoughts/opinion:
  • Are you typically making use of import/export by contract type?
  • Do you support concurrent use of multiple versions of a contract?  (assuming your contract interfaces are in strongly named assemblies)
  • If so, how do you handle contract name conflicts?
The reason I ask the question, is one of my biggest concerns with MEF at the moment is the current behavior whereby when supplying a type for the import/export attribute, contract name is derived from the simple name of the type.

I think this is a really bad decision - for a system which provides open-ended extensibility (I would argue) needs to support concurrent interface versions. This of course requires the use of strongly named assemblies for contract interfaces.  But, in addition, it really requires that contract name is derived using the assembly qualified name of the type - not the simple name.

I've given some input on this, but didn't really get any feedback on whether it would be seriously considered.

So, I'm wondering if this is an issue for you, and if so, what your opinion is on it.

Mar 9, 2009 at 4:14 PM

(wrote nice long post summarizing the default scenario, IE crashed :-( and I should get to work. Tell me if you have trouble understanding it or why I think the implication of doing defaults that way is exceedingly granular assemblies).

I'm still getting my head around the simple name implications and will comment later.

Mar 10, 2009 at 3:41 AM

You said here simple name, actually its the name qualified with the namespace. I know you've brought up using the full assembly versioned gigantically long name. Can you point me to that thread so I can read it before commenting. On first consideration, the namespace qualified value seems appropriate.

Mar 10, 2009 at 3:06 PM
Kathleen, you're right - I should have said namespace'd name.

The original posting is:


BTW, would have posted sooner - don't know if it's just my system but codeplex seems to be sloooow today.

Mar 11, 2009 at 5:54 PM
Edited Mar 11, 2009 at 5:55 PM
(edit: sorry, I meant to post this on your original thread)


Perhaps an easier way is to set your custom contract name directly on your interface using the ContractTypeAttribute.


Its kind of a bummer that this attribute is sealed, if you could subclass it and override the ContractName property it would be an easy way to provide a custom naming scheme.

Mar 11, 2009 at 7:19 PM
Thanks Josh.  That was something I considered - using the contract type attribute.  But it still suffers from having to manually update the contract name string - so, each time you release a new contract assembly, not only should you change the assembly version, you also must remember to go through the entire assembly and manually update the contract names for all the contracts.

That's kind of my original point - there are ways of handling this but they're a royal pain in the neck.  It cries out for using the assembly qualified name - then when I release a new contract assembly, I just make one change - update the assembly version and all the contained contracts are now appropriately identified as new contracts.

You're also right that if the attribute wasn't sealed, I could inherit from ContractTypeAttribute and create my own attribute class which did use assembly qualified name.  I suggested something very similar to this on the posting.  The MEF team are following framework guidelines whereby attribute classes should be sealed (I forget the rationale for this guideline).  My suggestion was though that they use an interface to retrieve the contract name.  That way I could implement the interface on my own attribute class and their original contract type attribute could remain sealed.

Alternatively, a reasonable compromise would be to have a flag on the contract type attribute which allows you to specify whether to use assembly qualified name or not.


Mar 12, 2009 at 12:44 AM

Historically the name/namespace has been the unique identifier (weird problems if you mess that up), so I think there would need to be an awfully good reason to use any other basis. I am not getting my head around your scenario.

I create and release a system.

I come back and make updates to the system. Interrfacces themselves do not version ( a general challenge in .NET), so where I make changes to interfaces, I give them new qaulified names (name + namespace, ignoring asembly). I leave the old interface in place, the same way I would if i changed the interface in another interaction with .NET

Where does this approach run into trouble. What do I need to manually change except the interfaces that rely on th new interface?

The problem I see with the flag is that I think you'd want to determine which you were using at the site of the contract, the export or the import. That more or less requires that the export storage include BOTH the qualified and fully qualified with assembly names. Without that, you would need the entire ecosystem to use the same approach and at least in my case an the VS case the edges of the ecosystem are exceedingly blurrry so (more or less) the whole world ideally uses the same approach (with any export/import driven system becuase the beauty of MEF (ducking Glenn's wrath here) is that in the long run you don't need MEF, just something that treats IMport/Export and all associated details the same way (like in my fantasies a MAF replacement).

Mar 12, 2009 at 2:54 PM
Kathleen, here's a bit more background on the rationale.  Sorry if it's a little long winded... :)

BTW, you mention MAF - the philosophy followed here is very similar to that of System.AddIn:
  1. Contracts once published must never change.
  2. Contracts must have the property of transitive closure - meaning a contract must not only include the immediate types used (usually your interfaces) but all types directly or indirectly referenced by these types.  Note however, contracts do not need to enclose primitive system types or other published contracts.
  3. If an alteration is to be made to a contract, it must be published as a *new* contract.
Now MAF enforces this itself by forcing you to seperately create and publish contract assemblies.

I follow exactly the same principle - place the set of related interfaces which make up a contract, and all the types they use in a contract assembly.  This then forms a boundary between the users of a contract and the implementer of a contract.  The contract will not change and therefore can be safely used by users and implementers of the contract.  The user and implementers however can version independently.

There are some other restrictions and guidelines I follow, but one of the most important is that all contract assemblies must be strongly named.

Now, when you discover you need to make a change to the contract, which includes even the smallest change to any type within the contract assembly, you must release a new contract.

You could as you state use namespaces for this and manually append a version number to the namespace for each changed type.   I have some additional concerns with this approach that I'd have to think about, including whether the principle of transitive closure may mean that you should not only change the namespace of the types which you have changed but also any other types which reference the type (directly or indirectly).... If you were following the above guidelines this might well end up being the majority of the types!

Here's the thing though - you still should update the assembly version.  After all, the previous releases of the assembly do not have the new interface definitions, so for safe versioning practices it needs to be released with a new updated assembly version number.

Now by default, .NET will fail assembly binds if the version number of an assembly does not match, so when you deploy your updated assembly by default the existing addins which implement the contract will fail to load due to a bind failure.  There are ways you can handle this - such as side by side deployment - i.e. have your directory structure include two contract assembly files - the old version and the new version.  Alternatively, you can use a publisher policy file to redirect bind requests to the new version.  Finally, you could require addins to be rebuilt with the new contract assembly.


Here's why I think that using assembly qualified name is the more appropriate option:

  1. You should change assembly version anyway whenever your contract assembly changes (even smallest change).
  2. Using assembly qualified name means you do not have to manually change the namespaces of the types in the assembly - they are disambiguated on assembly bind by the assembly version number.
  3. When you publish the new contract assembly, it's usually a fairly simple update process for implementers of addins, or users of the addin contract - they make a reference to the new release contract assembly and then rebuild their project (addin et al).  If there are any missing methods/types etc. they will get a build error.  Once tested they can publish the new addin version, which will have a reference to the new version of the contract assembly.  Publisher do not have to change any of the potentially large number of 'using namespace xxxxxx' declarations in their code.  The only time a publisher would have to alter 'using namespace xxxxx' references would be if they decided they wanted to release an addin which concurrently supported multiple versions of the contract (and contract assembly).
  4. There's an additional benefit with assembl qualified name - there is no potential for naming collisions between different contract publishers when using assembly qualified name - since each publisher uses their own publisher private/public key pair.  Although namespaces can serve the same function when prefixed with a unique publisher name, I think it's still a bit risky.

In my particular case, I have a directory structure which allows deployment of multiple versions of the same contract assembly.  Whenever I release a changed contract, I update the assembly version.  I use the assembly qualified name to identify contract.  All of this allows me to safely allow components to use different versions of the same contract within the host application.  Components publishers (addins, or addin users) can also optionally concurrently support multiple versions of the same contract.

The one area where this philosophy is a bit more of a pain is that even if I want to make a slight alteration to a contract assembly, I have to release a new contract version, which means that all the users of the contract must be rebuilt using the new contract assembly if they wish to support this new version.  I agree with the MAF philosophy though - I think this is the only really safe approach.

O.k., sorry I know that wasn't a short explanation!  Hopefully it was intelligible though.

So, what do you think?