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 Reflection.Emit
!
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.
The 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 Equals
, Exists
, or GreaterThan
. The operand value given to the delegate is captured for later use.
Perhaps the most interesting GetPredicate()
method is the one that retrieves CompareTo()
results:
The 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!