The CLR and COM versioning rules differ enough to create a huge pile of problems with System.EnterpriseServices (the .NET programming model for COM+). Here's my CLR-flavored update of a number of well-known COM rules that should help staying out of trouble on both ends. From the list one may be able to tell that I am really not a big fan of "automatic" upgrades a la MDAC ...
Staying sane in a hybrid world: Using Enterprise Services
Clemens' System.EnterpriseServices rules: (a) Interfaces
1. Interfaces are immutable. They cannot change shape, semantics or identity, ever, across space and time. You don't fix interfaces, you create new ones and discard the old ones.
2. Automatic class interfaces (System.Runtime.InteropServices.ClassInterfaceType.AutoXXX) are a great convenience feature. Never use them.
3. You must use [System.Runtime.InteropServices.GuidAttribute("....")] on every interface declaration you'll ever may want use with System.EnterpriseServices. No exceptions.
4. Managed types draw their identity from their name, namespace and the assembly they are implemented in. An interface's identity may never change, therefore the assembly identity may never change. => Assemblies containing metadata defining interfaces may never change. No version changes, revision numbers, no build-number increments, nothing. They never change.
5. Place interface declarations in metadata-only assemblies that only contain interfaces and lock away the source code in a remote place and forget that place. Compile them once and never recompile.
6. If you want to create derivative interfaces, reference the assembly containing the base interfaces, inherit from the bases and follow #1 - #5
7.-10. Start creating the prototypes for your Enterprise Services interfaces using XML Schema, WSDL and wsdl.exe now and store Schema and WSDL with your project. You will need them later, believe me.
Clemens' System.EnterpriseServices rules: (b) Components
1. Every ServicedComponent must expose all public methods and properties through well-defined interfaces. Period.
2. ServicedComponents are versioned. Managed types are versioned with an assembly-level granularity. If the assembly version changes, the component version changes and that means that for all COM/Interop purposes (and, hence, Enterprise Services) it must get a new Class ID. Rule: Never use [System.Runtime.InteropServices.GuidAttribute("....")] on any ServicedComponent definition. The runtime will keep CLSIDs stable across recompiles (and across machines) as long as the assembly version and the full name of the ServicedComponent (including the namespace) doesn't change and it will change CLSIDs if any of the two change: That's what you want.
Clemens' System.EnterpriseServices rules: (c) Applications
1. Applications are immutable. An Enterprise Services application (Name and AppID) is a well-defined composition of well-known ServicedComponents defined in well-known assemblies.
2. If you have a new version of a ServicedComponent assembly, it's placed into a new application. Unchanged ServicedComponents in the same application (must be from other assemblies) must be aliased into the new application. To make this easier:
3. If multiple assemblies share the same application, their versioning will always be synchronized. If the version of one changes, all others will change versions, too.
4. Never use lazy registration except when developing. Always install using something like regsvcs.exe /appname:"MyAppName v.1.0.x.x" or the equivalent programmatic tasks using RegistrationHelper.
5. The attributes [assembly:ApplicationIDAttribute(...)] and [assembly:ApplicationNameAttribute(...)] are fantastic for lazy registration. Use them with "#if DEBUG" only or just don't use them.
6. Tell all your buddies that for big apps, "xcopy deployment" isn't cool.