tags:

views:

344

answers:

4

In a WCF service, what happens if I add methods as operation contracts after clients (that consume the service) have completed their implementations? Will the existing clients have to modify their implementations even though they do not use the new operation contract methods?

EDIT: Will the clients have to update their proxy even though they don't use the new contracts?

+4  A: 

No, new operation contracts in the service will not break the client's interface. You can freely change your interface as long as the method signatures that the client relies on remain unscathed. This means that you can add as many new interface members as you wish.

Andrew Hare
+3  A: 

The answer to this depends on your point of view. I say that changing the contract at all violates the contract. That's why they call them "contracts".

Changing the service contract by adding additional operations "breaks" the client because it will change their proxy code. In many Enterprise environments, such a change requires a QA pass, even if the existing client code is not calling the new operations. Basically, by adding operations, you are editing the client code. In that sense, it's clear that QA is required.

There's no need to modify the service contract, when you can instead create a new service contract, and have a different service endpoint implement it. You can even have the new service implement both the old and new contracts, and share the exact same code to implement the old one with.

I'm also one of the old fashioned types who believe you should use a different namespace for a different contract. In at least a picky sense, the old and new contracts are different, so potentially the same name might mean different things between the two. This can be mitigated by having the new contract derive from the old, so that the old names will remain in the old namespace, yet new names would be in the new namespace.

John Saunders
How about if they don't update their proxy?
Nick
If I were to create another service contract to hold the new methods I could not provide one unified interface that would club together related methods.
Nick
@John Saunders: I agree with you but from a pragmatic standpoint I am sure you can see the benefit of putting new methods into a contract and thinking of it as a new version which is backwards compatible. That being said I agree with everything you said so +1 to you.
Andrew Hare
@Nick: a single service can implement more than one service contract. And, how about if they happen to update their proxy, just to make trouble for you?
John Saunders
A: 

If you're concerned about versioning, my advice would be to follow contract-first approach: WSDL should be the one to be versioned, since it's WSDL that you're exposing to your clients when they want to use your service. Leaving WSDL to be changed by WCF (or any other web service technology for that matter) without your direct control will sooner or later cause you (or your clients) pain.

See WCF - contract-first vs. code-first and some suggestions on the workflow.

Igor Brejc
@Igor: this isn't an issue with WCF, as the service contract, operation, data, fault and message contracts are pretty much one to one with the WSDL. It's not like ASMX services, which tried to interpret what you meant, then created the WSDL from that.
John Saunders
@John: true, but still - WSDL is a valid contract between clients and the server, not the C#/Java/... client/server code, and as such should be treated with "respect".
Igor Brejc
A: 

I've just implemented a solution to a similar situation. Initially I just created a new interface extending the current ServiceContract, using Service Contract Inheritence, updating the endpoint definition to deliver the new derived interface (as suggested in this article).

This was fine for other .net applications that were connecting, those looking for the 'old' interface got that and those looking for the 'new' got that one instead.

The problem was that I had a non .net app which was looking for an explicitly hard-coded binding, BasicHttpBinding_IOriginalInterface, but the new service was offering BasicHttpBinding_IDerivedInterface.

By unifying both interfaces with a common ServiceContractName [ServiceContract(Name="IOriginalInterface")], this got around that issue, as recommended by this article.

Unsliced