views:

589

answers:

6

In our C# code, we have a class called Project. Our base BusinessObject class (that all business objects inherit from) defines a property:

public Project Project { get; set; }

This is normally not a problem as long as we stay within the C# codebase. However, these business object classes are exposed in web services over the wire. Some consuming languages (such as Flex's actionscript) cannot handle having a property with the same name as its class.

This naming conflict happens all over the place in our code. Sometimes it's easy to change the name of the property or class. Sometimes it's really hard. We've wracked our brains and can't come up with a good standard way to handle this. It's possible to rename the Project class to ProjectType or ProjectInfo, but this is ugly and breaks all of our consumers' existing code. We could leave the type name the same and change the name of the property to ProjectInfo, but this causes the same problem.

Does anyone have any guidance or best practices for such a situation?

EDIT: Responding to some of the suggestions given:

  • Methods aren't exposed over the wire, so we can't use methods.
  • I'd prefer a standard naming convention that also adheres to Microsoft's own naming standards.
  • Exposing a different contract for Flex may be an option. However, we're using Weborb for Flex interop. Weborb uses reflection to match the property names exactly, rather than using XML or SOAP serialization. If anyone knows more about custom serialization with Weborb, that would be helpful.
A: 

I use camelCase instead of UpperCase, for the name of members (methods and properties).

This is against the standard naming conventions, however, so I can't call it a "best practice" (but, it's what I like).

So, in your example I'd be defining:

Project project { get; set; }
ChrisW
... and your code looks completely at odds with the rest of .NET. Consistency trumps personal preference IMO. I hope you'd at least fit in with the normal conventions if you were creating a library for third parties to use.
Jon Skeet
You've commented on this before. My code's looking at odds with the rest of .NET works for me (and I'm consistent with myself, not with the base class library): I can tell whether code is invoking `myCode` or `SystemCode` just by looking at it, even in a subclass of a system class.
ChrisW
And that's a good thing why, exactly? I think we'll have to agree to differ, but I hope you realise that almost every .NET development company in the world also follows the standard convention. We're not just doing it for the sake of it - it makes the code more readable.
Jon Skeet
I hope your consumers aren't case-insensitive then (*cough* VB *cough)
Marc Gravell
I realize what the standard convention is; but how is "makes the code more readable" any more than a subjective and unproven assertion? Apart from the matter of mere taste, I pointed our that being non-standard *adds* information (i.e. you can see the difference between `myCode` and `SystemCode`).
ChrisW
We're trying to stick with standards as much as possible in this project. The standard way to differentiate between System code and My code is with namespaces.
davogones
A: 

How about good old methods? (GetProject/SetProject OR the way .net does it - Thread.CurrentThread)

shahkalpesh
Except properties on web-services proxy objects are metadata-based only: no methods, only data...
Marc Gravell
Yeah, methods don't get exposed over the wire, only properties and fields. So that won't work unfortunately.
davogones
+3  A: 

It sounds like you've got an intractable problem if you've already got the web service out there with the problematic name. If you can't change anything without breaking existing customers, and you can't leave it as it is without breaking Flex, someone's going to be broken.

You could potentially expose a parallel API at a different URL. I'd agree with shahkalpesh's suggestion of Get/Set methods where the properties would be problematic. The good thing about this is that you can make the decision once and then be consistent rather than needing to think about it each time. It also means you can probably automate the creation of the second API based on the first.

Jon Skeet
We're aiming for a solution that doesn't break Flex. We can refactor the .NET code, it will just take some time. I was hoping maybe there is a standard naming convention that would prevent this problem from happening again.
davogones
As mentioned, methods aren't exposed over the wire so they won't help. Exposing a different contract might be an option. However, we're using Weborb, which has their own serialization scheme that uses reflection to find the exact member names instead of using xml serialization.
davogones
The standard .NET naming conventions don't try to address this because it's usually not a problem. It sounds like the technologies you're using aren't really up to the job :(
Jon Skeet
A: 

WTF has the name of a variable in one language got to do with a web service?

Someone has to be really lazy in their XML binding for implementation details to be exposed on the wire.

The whole point of WSDL/SOA is that you have a spec for a message which is independent of implementation. If you generate message specifications from source code, or generate source from the specifications without allowing for variation of the generated objects, you end up with tightly coupled systems. One symptom of this tight coupling is getting variable/property names that aren't legal identifiers. A service (rather than an RPC) is not tightly coupled. You should not have to vary your service implementation to cater for the implementation of the service - if you have to, something in your stack is broken. That goes for member variables/properties as well as methods.

Pete Kirkham
Who mentioned variables? The class / property names form part of the metadata for a WSDL-based web service. The names chosen are valid (if unfortunate) - if anything the flex binder is substandard...
Marc Gravell
Member Variable is another terminology for 'property'
Pete Kirkham
A: 

Although it's not really of help for external languages it is possible to alias namespaces (presumming the class Project is in a difference namespace to the class with the property Project), like so:

using ns = MyProject.Namespace;

Then you just have to do:

var newProject = new ns.Project();
Slace
I don't really see the relevance this has to do with the question since it has to do with the object being exposed over a WSDL not in his internal code.
Chris Marisic
+2  A: 

I think the best solution is refactor your project to rename the object Project to something else WnProject, ProjectBase, or something else relevant to what exactly project is.

It's your API, anyone consuming it has to understand it's possible to have breaking changes shipped it's the cost of being dependent on external sources.

Chris Marisic