質問

I'm designing some services and I would like to get some feedback about the conventions I'm using.

For all operations, I always define a 'Context' object and a 'Result' one, because of the following advantages:

  • extensibility: I can add parameters to the context or objects to the result without changing the interface
  • compactness: I only have a single object in the definition, even if I need many parameters

Example:

[OperationContract]    
DoSomethingResult DoSomething(DoSomethingContext context)

Anyway, I'm not really sure that this is the best way to do it because of the following reasons:

  • overhead: I always wrap the response properties into an object. Sometimes, the Result object has no properties
  • versioning: WCF has built-in versioning for contracts, and maybe it could be better to use a different version to inform about the difference

In fact I use the same technique with normal methods too, so it would be important for me to get some feedback, advices, critics and so on and so forth.

Thank you

役に立ちましたか?

解決

I think that's a perfectly legitimate way to write your contracts. I've worked on a number of projects with these sort of contracts and it is has been a pleasure - very easy during development (just add a property to the object and you're done), a straightforward and clear pattern that applies to all services, and allows for things like a single validation method for all operations.

In response to your concerns:

  • I don't think the overhead of creating an empty object is at all significant. Don't worry about this unless it becomes an issue.
  • If the Result object has no properties (i.e. you aren't returning anything) then simply return void. You aren't gaining anything by returning an empty object.
  • You can (and probably should) version these objects as you version your contracts. What you are doing in no way precludes you from versioning your objects.

Please note that versioning objects does not mean changing them to DoSomethingResult_v1, DoSomethingResult_v2 as I've seen before. You should version with namespaces; it makes things clearer and cleaner. Just put a version in the XML namespaces in both the operation contract and data member attributes.

他のヒント

I don't think there are any performance concerns here, and the code looks easy to work with from the code-owners perspective.

My big concern is that it isn't at all clear from the consumers perspective how your service works. They would have to rely on separate documentation or error messages.

It would be much easier for someone unfamiliar with your code (i.e. just downloaded the WSDL) to consume your service if the parameters that it required were declared. You also get a good degree of validation out of the box.

To illustrate:

[OperationContract]     
DoSomethingResult DoSomething(DoSomethingContext context) 

vs

[OperationContract]   
[FaultContract(typeof(CustomerNotFoundFault))]   
Customer GetCustomer(UInt32 customerId) 

This point is mostly relevant to the design of APIs. Where this isn't so relevant, is where you are both the author and the consumer of the service.

I totally support Kirk Broadhurst's suggestion of using namespaces for versioning. I use that and it works well.

EDIT: on a second reading, I think I misread your post. I was assuming here that your parameter and return value objects were some generic object that you use across all services. If indeed they are specific to each service, then that's a great approach which I've used successfully on many occasions. You'll do well with it.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top