Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coerce types in different namespaces with Identical layout in C#

I've started writing an interface for FedEx's webservice APIs. They have 3 different APIs that I'm interested in; Rate, Ship, and Track. I am generating the service proxies with SvcUtil.exe.

The different service endpoints are each specified by FedEx in their own WSDL files. Each service endpoint has it's own xml namespace (e.g. http://fedex.com/ws/rate/v5 and http://fedex.com/ws/ship/v5)

The service endpoints do use quite a few identical types such as Address, Measurements, Weight, AuthenticationDetail, ClientDetail, etc...

And here is where the problem lies, I can provide all the WSDL files at the same time to SvcUtil.exe and normally it would coalesce any identical types into a single shared type, but since each of FedEx's services are in their own namespace, and they redeclare these types in each WSDL file under that namespace what I end up with instead is an Address, Address1, and Address2 one for each namespace.

To solve that issue, what I do now is to run each WSDL through svcutil separately and put them each in their own .NET namespace (e.g. FedEx.Rate, FedEx.Ship, FedEx.Track). The problem with this is that now I have a distinct address type in each namespace (Fedex.Rate.Address, FedEx.Ship.Address).

This makes it difficult to generalize the code used between the services like a GetAuthenticationDetail() factory method so I don't have to repeat that code in every place I use the different services.

Is there any way in C# to Coerce FedEx.Rate.Address to FedEx.Ship.Address?

like image 676
joshperry Avatar asked Feb 18 '09 19:02

joshperry


1 Answers

If the types are identical, and you have control over the source classes, you can define a conversion operator in the class, and any function that takes a Rate.Address will also automatically take a Ship.Address. For example:

namespace Rate {
    class Address {
        string Street;
        string City;
        // ...

        public static implicit operator Ship.Address(Rate.Address addr) {
            Ship.Address ret;
            ret.Street = addr.Street;
            ret.City = addr.City;
            // ...

            return ret;
        }
    }
}

My C# is a little rusty but I hope you get the idea.

like image 56
zildjohn01 Avatar answered Oct 05 '22 17:10

zildjohn01