views:

112

answers:

2

We are using a Microsoft ERP which dynamically exposes web services. The services generated by the service is out of our control. We have no say so in how the objects, including the type definitions, are created and exposed. When a new method is added or removed from the web service, all of the type enumerations are renumbered and everything that uses the web service, after updating to the new definitions, is hosed up. So essentially,

enumeration Type1
  Item1
  Item2
  Item3

... could become

enumeration Type6
  Item1
  Item2
  Item3

...with the enumeration type name changing, but members of the type remaining static. The service outputs a service which looks exactly like the end result of using the XSD.exe to generate objects. So anytime someone exposes a new method on the service (via the ERP GUI), the objects are rebuilt, types are assigned to the service definitions in alphabetical order, reexposed, leaving the entire code base shot.

I attempted to use reflection to determine the type and then parse out the static member into the new business object, but it doesn't work because I can't type cast the enumeration without knowing the actual name of the type. The following won't work.

System.Type t = service.BusinessObjectEnumeration.GetType();
service.SomeField = Enum.Parse(t,"Item1");

...as the compiler throws an error because I'm not explicitly casting the enumeration.

Any ideas how I can overcome this issue while dynamically casting the type to the correct enumeration?

Again, I cannot modify the actual objects exposed by the service, only the code subscribing to the service.

Thanks, George

A: 

Why should you need to parse things?
If I understand Enums correctly, they pass on the value (and not the Enum itself).

EDIT: What I mean is, enum is not same as a class. For a class, one expects an instance to be passed/received. For an enum, it is one or combination of its members, which is passed in form of an int value.

EDIT2: Are you trying to use the enum as some kind of struct here?

EDIT3: You will have to see what type is the enum in debug mode, to figure out how to reflect on it.

object enumValueReturned = service.BusinessObjectEnumeration;

Put the enumValueReturned in watch window & play with it using reflection (GetMembers) to see, how would you reach Item1.

shahkalpesh
-1 There are a number of reasons why you could need the name or string value of the enum, e.g. maybe some XML serialization saved the string values, maybe they are used to populate a dropdown, etc, and you want to hang on to the name of the enum if a new value is added in the middle. All of these uses might not be the smartest of practices, but they are practices nonetheless.
SWeko
@Sweko: How is the enum values passed over from webservice? Does it pass the entire metadata of an enum alongwith actual value? I mean, what is the point of an Enum, when you are looking for one of its member value?
shahkalpesh
The Enum metatada is generated on the client when the Web Service is referenced, and then, at runtime, that metadata is used in the request/response calls. And I agree, int's are way more portable for web-service usage, but the OP does not have control over the service.
SWeko
+2  A: 

Re the exmaple code:

System.Type t = service.BusinessObjectEnumeration.GetType();
service.SomeField = Enum.Parse(t,"Item1");

Maybe the way to do this is via reflection:

var prop = service.GetType().GetProperty("SomeField");
prop.SetValue(service, Enum.Parse(prop.PropertyType, "Item1"), null);
Marc Gravell
I suppose that using reflection to both retrieve the value and set the property is the only available way, given the OP constraints.Of course this means that even methods that use such enum as a parameter should be invoked using reflection (since it is agnostic regading parameter types)...
BladeWise