2009-01-16

Mapping Cargos to Objects returned from a Web Service using Reflection

Background:

When working with webservices, we wanted to use a common library of cargo objects that would be used for sending data between the tiers of the application. The Middleware tier has all the web references, and also has methods that encapsulate the web references objects, essentially wrapping them to common cargo objects. After all, we would not like to have dependencies to types that are defined in the auto-generated web service proxies.

One way:

One way of creating the cargo objects is to copy the code for the classes from the Reference.cs file into the common cargo objects assembly. Then you could wrap the objects from the web service dependent object to the common cargo objects which would then be passed to the application tier.

Problem:

It's a lot of work to type all the code for wrapping the objects...

Solution:

Since the cargo objects have the same properties as the web service proxy objects with the same names, it is possible to do the wrapping by using reflection, for instance using a method like this:

private void wrapToCargo<T,U>(T source, U cargo)
{
//Gets all properties from the source object...
PropertyInfo[] props = source.GetType().GetProperties();
//Loops the properties...
for(int i = 0; i < props.Length; i++)
{
//Checks if a property with the same name is present on both the source and the cargo,
// and if the property is writeable.
string name = props[i].Name;
if (source.GetType().GetProperty(name) != null && cargo.GetType().GetProperty(name) != null && cargo.GetType().GetProperty(name).CanWrite)
{
//If so, set value of the cargo property to the value of the source property.
cargo.GetType().GetProperty(props[i].Name).SetValue(cargo, source.GetType().GetProperty(props[i].Name).GetValue(source, null), null);
}
}
}


Alas, this generic way of wrapping cargos comes at a cost. I would suggest that one should wrap from the target (loop through properties of the target, then match with properties belonging to the source object) in stead of the source as shown above, because you will have more control of what fields should be mapped.

No comments:

Post a Comment