Last time, I talked about the mapping document parser component of my object mapper.
The other component, the Conversion Engine, is the workhorse of the Object Mapper. Its ObjectConversionEngine class is the public interface to conversion functionality, and it exposes methods with the following signatures:
The first two signatures are used when constructing a new instance of the target object. The generic overload makes use of the extra type information to attempt to use .NET type converters when all else fails. The final signature is used when updating an existing target object.
When asked to convert an object, the engine will first try to locate a mapping that matches the source and target object types. If it finds a mapping, it invokes the mapping’s Command against the source object. Being a Composite, the invocation will cascade down to each individual leaf element.
I wanted to mention two things about this process. Because we may need to create an object in a multi-step process, a Source can have multiple Targets. After each Target’s command is executed, the result is cached in the ObjectFactory so it can be injected by a later command.
However, it’s easy to imagine a situation where I may want to do something conditionally. For example, if I have an array of addresses on my source type, my destination type may have a PrimaryAddress property and a SecondaryAddresses array. In this case, I want the first address of the source to map to the PrimaryAddress property and the rest to go into the array.
For this, I need a new type of command, a ConditionalCommand. The XML looks like this:
I thought about how to implement this for a while. When I specified this feature, I’d envisioned using expression trees. When I found out I was restricted to C# 2.0, I even spiked a version using an IL generator to create methods programatically using
IL generation is not for the faint of heart, and I told myself there’s got to be a better way! What I wanted originally was a lambda, which thanks to J.P. Boodhoo’s Nothin’ But .NET course I knew was just syntactic sugar for delegates.
I defined a Condition delegate type:
And then I created a
ConditionalCommandBuilder to create them. It’s really a Factory class, but I preferred the name “builder” here. It uses a fluent interface, so the If methods return a
ConditionalCommandBuilder for chaining.
GetPredicate() command returns a
Predicate, which is a delegate defined in the .NET Framework. The operation variable defines what type of predicate to retrieve, such as
GreaterThan. The operand value given to the delegate is captured for later use.
Perhaps the most interesting
GetPredicate() method is the one that retrieves
TypeResolver class is analogous to the
MethodResolver class I talked about in a previous post, but it finds types by name instead of methods.
One advantage to coding with design patterns is that they isolate concerns. Once I got a
ConditionCommand to be created correctly, the rest of the conversion engine worked like a charm!