views:

151

answers:

2

What are the most important guidelines to follow if you need to break an interface in a .NET application? How do these guidelines change before and after your application has been deployed?

I know there are other questions that debate when/where interfaces should be used, however I don't want to get into that. I just want to know some effective approaches to mitigating effects on the rest of your application when you need to do this.

If I am just adding new method/s to an interface, will only implementors need modification/recompile, while all clients continue to operate happily with no change required?

What about renaming methods and variables, is this ever going to break an interface?

One strong recommendation I've come across in the past is "never break an interface". But doesn't this produce a messy design such as IDocument, IDocument2, IDocument3, IDocument4, IDocument5, IDocument6 etc, as seen in the mshtml COM library?

+1  A: 

This certainly depends on technology. In COM (when not using IDispatch late binding) you can safely add new methods at the end of the interface but cannot remove or swap previously existed methods without changing the interface GUID. Same applies to Microsoft RPC. Older clients can still be happy using the interface like it only has the methods they know about.

sharptooth
Thanks for the response. I've decided to focus it on the .NET platform as my question was probnably a bit too broad.
Ash
+4  A: 

It depends on the contract (implied or explicit) with the consumers of your interface.

If all consumers are rebuilt when you rebuild the interface then managing changing it is simple, simply change it and fix all the breaks (fixing the breaks themselves may be complex).

If you expect consumers to to a recompile whenever you release a new library/app then you will need to provide some assistance to them to indicate what changes are required, how you manage this is dependent on whther the change can happen whilst maintaining the old functions/properties. If you can then judicious use of [Obsolete("Use the new Blah method instead", false)] in at least one release followed by [Obsolete("...", true)] in the next release will provide a clean migration path

If you try to maintain binary compatibility then the Obsolete attributes allow for this while still stopping people continuing to use the deprecated functionality when they recompile.

If your contract implies that binary and source compatibility is to be maintained for, say 5 years (a short period of time for OS platform APIs) then you have little choice but to go with an entirely new interface, adding methods to an interface will break code implementing it (either at compile, at type validation or at method invocation depending on the strictness of the type loader).

ShuggyCoUk