What to do when property name matches class name
Asked Answered
H

6

14

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.

EDIT #2:

For reference, we ended up renaming the property to something like:

public Project ProjectInfo { get; set; }
Hera answered 8/2, 2009 at 7:15 Comment(0)
H
4

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.

Hammon answered 8/2, 2009 at 7:50 Comment(3)
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.Hera
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.Hera
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 :(Hammon
L
2

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.

Lawton answered 8/2, 2009 at 16:58 Comment(0)
D
0

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

Delouse answered 8/2, 2009 at 7:28 Comment(2)
Except properties on web-services proxy objects are metadata-based only: no methods, only data...Marybethmaryellen
Yeah, methods don't get exposed over the wire, only properties and fields. So that won't work unfortunately.Hera
V
0

I know this is an old question, but it might help others.

Why not provide a different WSDL for consumers that don't support the same prop name and type?
Rename the complextype in the WSDL (NOT the element name!)

From what you (should) have now:

<xs:element name="Project" type="Project"/>

<xs:complexType name="Project">
  <xs:sequence>
    <xs:element name="Title" type="xs:string"/>
    <xs:element name="Description" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

To:

<xs:element name="Project" type="ProjectType"/>

<xs:complexType name="ProjectType">
  <xs:sequence>
    <xs:element name="Title" type="xs:string"/>
    <xs:element name="Description" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

In this case, the SOAP-message would remain exactly the same, meaning you don't have to recompile your solution nor provide another service.
Also, other consumers won't have to change anything.

Ventral answered 21/3, 2013 at 8:44 Comment(3)
By now it's been years since I've worked with web services in .NET! If memory serves correctly, the WSDL is autogenerated and cannot be customized. Is there an attribute that allows you to customize the autogenerated property name?Hera
I have not tested this, but I think the attribute you're looking for is: System.Xml.Serialization.XmlRootAttribute as shown on msdn.microsoft.com/en-US/library/awac9czf(v=vs.80).aspx Alternatively, you can disable showing the WSDL (adding ?wsdl to the url) to consumers (#3477555) and provide them seperate WSDL's depending on the consumers technology.Ventral
It's been years and my .NET knowledge has gotten rusty, but it seems that XmlRootAttribute is used for types rather than attributes. As for providing a separate WSDL / endpoint, that would be a pretty onerous maintenance burden. We had many services and contracts to maintain and expose. During the life of the project I never manually touched a WSDL file.Hera
A
-1

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();
Amphibrach answered 8/2, 2009 at 10:13 Comment(1)
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.Lawton
T
-3

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.

Todo answered 8/2, 2009 at 9:52 Comment(2)
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...Marybethmaryellen
Member Variable is another terminology for 'property'Todo

© 2022 - 2024 — McMap. All rights reserved.