Short review: Celtx, script writing software

2010 February 5

Celtx is a free media pre-production software package. I was looking for a text editor that understood movie script formatting, and Celtx certainly does that. The Windows and Mac versions of Celtx work seamlessly together. I started my current project on Windows and am continuing on the Mac.

Those familiar with a word processor should feel right at home with Celtx. Switching between scene headings, exposition, character slugs, wrylies, and dialogue is deftly handled through tabbing and line breaks. Each scene and character introduced is added to the Master Storyboard section, a central repository for information about the story element, including the capability to store images and the like, though I have not used it for such yet.

While writing in Celtx is easy, I would request some features for editing. Sometimes I struggle with getting a particular element in the right category. It is easy to an element’s type with a dropdown, however this combined with the automatic addition of scenes and characters to the Master Storyboard can be trying. I would like the ability to scan the Master Storyboard and have Celtx prompt me to delete any elements that no longer exist in the script.

Being a programmer whose used to working with source code refactoring tools, I’d also like some “refactoring” tools in Celtx. For example, I’d like the capability of intelligently renaming a character, one that paid attention to casing, or even change the character’s gender. I’d also like the ability to rename a scene location. Going further, I could even imagine some style rules engine, maybe offering to capitalize sound verbs in some script styles.

Celtx does offer some reporting, such as showing all of the dialog. And its PDF rendering is nice. It would be nice if it showed what page number you would be on, though, as I find for pacing purposes, I’m often invoking the PDF rendition just to determine what page a particular scene is on.

For free, it suits my needs admirably, and I think their Celtx Studios online tools look intriguing. Having said that, Celtx has greater potential. I look forward to seeing the product grow.

Code Documentation with Sandcastle and doxygen

2010 January 11

Last time, we talked about accepting file input, the last feature added to the Object Mapper. Now, it has come time to document the module.

I use ReSharper to help code in Visual Studio, but it still doesn’t generate XML comments as well as I’d like, so I also use GhostDoc, which turns code into better English than ReSharper does. There is still editing to do, for while describing the code in English is marginally useful, GhostDoc still cannot provide context.

Finding missing documentation was trial and error until I installed the AgentSmith ReSharper plug-in, which made finding them a breeze after I turned solution-wide analysis on and marked missing documentation as a ReSharper error. Once I had all the classes, properties, and methods documented, I set out in search of a tool to convert those XML comments into something nice.

The first tool I tried was Microsoft’s Sandcastle. Sandcastle itself is tough to use, so I went to CodePlex and also downloaded the Sandcastle Help File Builder. It does a nice job of creating HTML and compressed help files (CHM).

I did have to alter a few things. I wanted namespace comments, and dug around a little before I discovered the Project Properties -> Comments expansion button on the right, and I typed those in. I did want to avoid outputting VB.NET and C++ contextual references, so I had to go into the Syntax Filters dialog and disable them. I also customized the root namespaces, help title, HTML help name, and copyright text, and I was ready to go.

But the requirement was to generate the documentation in Word. For as good as Sandcastle is, it doesn’t seem to do anything but HTML and CHM.

The next tool I tried was doxygen. It’s a UNIX tool with Windows binaries, so it took a little more cajoling. At first, it wouldn’t generate any content at all, but I got it working in short order after I saved its configuration file prior to rendering.

doxygen also supports more formats: LaTeX, RTF, and MAN pages, though it won’t do CHM. RTF is a close cousin to Word document formatting, so I had high hopes. However, I found the generated RTF document disappointing, and later found a forum where the author admitted as much.

LaTeX is a great layout specification language, so I thought it might be a decent stepping stone to a Word doc. I spent a merry while trying to monkey with LaTeX2RTF, a free converter on sourceforge, but the results were disappointing. It couldn’t understand doxygen’s custom elements.

I’m still looking for a better solution, any ideas?

Object Mapper: Accepting File Input

2010 January 8
by neontapir

The work on the Object Mapper is nearly complete from when we left off with the conversion engine.

I did enhance the parsing engine, though. My co-worker was trying to consume the engine, so he was reading in his document and extracting the text. We decided this was a common enough activity it would be worth adding to the parsing engine.

I didn’t want to pass in the filename as a string, because it would mean that the parsing engine would also become responsible for determining if a string contained a filename or an XML string. One rule of thumb is to avoid using primitives like strings to represent concepts — things with rules — like filenames. Instead, create a class to be the custodian of that knowledge.

The .NET Framework already has such a class, System.Uri. The nice thing about using a URI is that any network location can also be used, not just a filename, and I get some simple validation capability.

Integrating the URI was easy. The parsing engine wraps the input string into a StringReader and creates an XmlReader from that with which to do its work. And really, any TextReader would do, which made the enhancement easy. I created an overload that accepts a URI and wraps it in a StreamReader, which is also a TextReader. Problem solved!

Object Mapper: Conversion Engine and Conditional Commands

2010 January 6

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:


object Convert(object source)
T Convert(object source)
object Convert(object source, object target)

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:

<Object Source=""System.String"" Target=""System.String"">
<If Operation=""Equals"" Operand=""SomeValue"">true</If>
<Else>false</Else>
</Object>

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:


bool Condition(object source, out object result, params object[] arguments)

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.

public ConditionalCommandBuilder IfObject(string operation, object operand, ICommand command)

{

    Predicate predicate = GetPredicate(operation, operand);

    Condition condition = delegate(object source, out object result, object[] arguments)

                            {

                                if (predicate(source))

                                {

                                    result = command.Execute(source, arguments);

                                    return true;

                                }

 

                                result = null;

                                return false;

                            };

    _conditions.Add(condition);

    return this;

}

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, orGreaterThan. 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:

private Predicate GetCompareToPredicate(object operand, ICollection compareToValues)

{

    Predicate predicate = delegate(object source)

                    {                                       

                        Type type = source.GetType();

                        MethodInfo compareTo = type.GetMethod(“CompareTo”, new Type[] { typeof(object) });

                        if (null != compareTo)

                        {

                            object converted = TypeResolver.ConvertTo(type, operand);

                            return compareToValues.Contains((int)compareTo.Invoke(source, new object[] { converted }));

                        }

 

                        throw new Exception(string.Format(“{0} must implement CompareTo(Object) to use the GreaterThan conditional”, type));

                    };

    return predicate;

}

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!

Review: dotTrace 3.1

2010 January 5

When running some unit tests for the Object Mapper project, I found the test suite’s execution time had slowed down noticably. I had been spoiled at my previous employer, where I had access to ANTS Profiler. So, I set about finding a performance profiling tool.

While there are some free profilers out there, the reviews on the web led me to believe they wouldn’t be up to the task. I was drawn to dotTrace because of its ReSharper integration. I decided to give it a go with their 30-day trial.

What you will read in forums is absolutely true: ANTS provides more data, with ReSharper, dotTrace is much easier to use. And, I have learned that more data is not necessarily better.

It seemed that dotTrace could not trace the code execution once it had been loaded into ReSharper’s test runner thread, so I had to write a quick console app to exercise the code I wanted to check.
dotTrace was able to pinpoint the area of code that plagued me, where I was doing some repetitive MethodInfo lookups. Some caching brought the performance back in line with what it had been.

During this tweaking process, I found dotTrace’s capability to compare test runs to be invaluable! I was able to see in percentage terms how much things improved with the caching. I also removed the caching and saw the performance degrade as expected, so I could be sure it wasn’t coincidence. And, I am happy to report that the Console.WriteLine statements in the console app were the most time-consuming piece of the process, so my engine ought be able to withstand the load I understand it will receive in production.

I strongly considering buying dotTrace when my trial expires. It’s a good tool to have in the toolbelt.

Object Mapper: Challenges of inferring type information

2010 January 4

I left off last time talking about array transformation Commands, and mentioned they highlighted the troubles with inferring type information.

Remember that the parser can take a signature of


object Convert(object source)

The reason all of the Convert methods do not take generics is for Java interoperability. Because the method can take any object, I need to lean heavily on the Reflection library to infer type information. (This is a situation where the new dynamic typing in C# 4.0 would have been invaluable!)

For example, let’s take the ElementSetter command. In IronRuby or C# 4.0, this would be a piece of cake. In Ruby, I could simply say something like:


property_name = "Name"
# ... stuff ...
target.send(property_name, source.send(property_name))

Instead, I have to use type metadata to do the work:

public override object Execute(object sourceObject, object targetObject)

{

    ElementInfo sourceProperty = new ElementInfo(sourceObject.GetType(), _source.ID);

    object sourceValue = sourceProperty.GetValue(sourceObject);

 

    ElementInfo targetProperty = new ElementInfo(targetObject.GetType(), _target.ID);

    targetProperty.SetValue(targetObject, sourceValue);

 

    return targetObject;

}

The ElementInfo class serves as an Adapter for the Reflection library’s PropertyInfo and FieldInfo classes, so that I can treat properties and fields the same throughout the rest of my code. The ID property of the _source and _target variables contain the name of the property. Under the covers, the ElementInfo class just defers to the appropriate instance of either a PropertyInfo or FieldInfo class.

The logic behind finding the right MethodInfo object to represent a conversion function is a little more challenging. I wrote a MethodResolver class to handle the lookup of a method by its name. It can find both instance and static methods.

Another responsibility of the MethodResolver class is handling generic types. Using the Type.GetMethod() method, I can get a MethodInfo object. MethodInfo contains a method ContainsGenericParameters(). While that is true, there are open generic parameters to the method that need to be bound.

The last challenge to mention in this post is the creation of objects. How can one create a new instance of an arbitrary type. Generics provide some useful constructs like default(T), but there is no convenient way to invoke this language feature outside of a generic method. And, as it turns out, default(T) doesn’t always give me the answer I want.

I stumbled upon this in writing the array Command Decorator. I have an array of strings. I want to fill an array of integers by converting each member of the string array to an integer. But where do I get the new array from?

I tried a few casting solutions, but found that if I used an object[], for example, the objects inside the array would appear to lose their type information and be just objects, which caused problems later in the process.

I also tried to write something like:


T[] destination = new T[](_source);

I have an issue, though. This generic method must now have the constraint new(), which means I have to handle arrays as a special case.

I found that by creating an ObjectFactory class, it simplified other areas of the code. The ObjectFactory, being a Factory, knows how to create new objects. It also holds a cache of previously created objects.

public object Create(Type targetType)

{

    if (targetType.IsAssignableFrom(typeof(string)))

        return string.Empty;

    if (targetType.IsAssignableFrom(typeof(DateTime)))

        return DateTime.MinValue;

    if (targetType.IsArray)

        return Array.CreateInstance(targetType.GetElementType(), 0);

 

    try

    {

        return Activator.CreateInstance(targetType);

    }

    catch (MissingMethodException e)

    {

        throw new Exception(string.Format(“No parameterless constructor for type {0}”, targetType), e);

    }

}

Activator lives in the System namespace, and it’s what the .NET Framework uses for instantiating objects in AppDomains. It works for my purposes, but as you can see, I did end up with some special handling of arrays in the end.

Having talked about some of the challenges of type inferrence, next post will discuss the conversion engine itself.

Object Mapper: Bridging the Gap

2009 December 31

Recently, I talked about the generation gap I faced when considering elements at different levels of the hierarchy. I have a partial solution.

Recall I have the following hierarchy of objects:

Person { Name : string }
Parent { Children : Person[] } is-a Person
Grandparent { Grandchildren : Person[] } is-a Parent

So, I created the following test classes:

public class Person

{

    public string _name;

 

    public string Name

    {

        get { return _name; }

        set { _name = value; }

    }

 

    public Person[] Siblings;

    public Person[] Parents;

}

 

public class Parent : Person

{

    public Person _firstborn;

 

    public string FirstbornsName;

 

    public Person Firstborn

    {

        get { return _firstborn; }

        set { _firstborn = value; }

    }

 

    public Person[] _children;

    public Person[] Children

    {

        get { return _children; }

        set { _children = value; }

    }

 

 

    public object this[int index]

    {

        get { return _children[index]; }

    }

}

 

public class Grandparent : Parent

{

    public Person[] _grandchildren;

 

    public Person[] Grandchildren

    {

        get { return _grandchildren; }

        set { _grandchildren = value; }

    }

}

Obviously, these test classes will never form the basis of a top-notch genealogy program, but they are adequate to serve my purpose.

And, with the changes I’m about to describe, I’m able to write a passing test like this:

        [Test]

        public void Grandchildren_test()

        {

            string xmlToParse =

                string.Format(

                    @”<?xml version=”"1.0″” encoding=”"utf-8″”?>

<Maps>   

    <Source ID=”"source1″” Type=”"{2}”">

        <Target ID=”"target1″” Type=”"{1}”">

            <Element Source=”"Children”" Target=”"Siblings”" />

            <Element Source=”"Grandchildren[0]“” Target=”"Firstborn”" />

            <Element Source=”"Grandchildren[0].Name”" Target=”"FirstbornsName”" />

            <!– <Element Source=”"Name”" Target=”"Parents[0].Name”" /> –>

        </Target>

    </Source>

</Maps>

, typeof(Person).FullName, typeof(Parent).FullName, typeof(Grandparent).FullName);

 

            MappingDocumentParsingEngine parser = new MappingDocumentParsingEngine();

            List<ElementBase> elements = new List<ElementBase>(parser.Parse(xmlToParse));

            ObjectConversionEngine converter = new ObjectConversionEngine(elements.ToArray());

 

            Grandparent ellis = new Grandparent();

            ellis._name = “Ellis”;

 

            Person andy = new Person();

            andy._name = “Andy”;

 

            Person steve = new Person();

            steve._name = “Steve”;

 

            Parent charles = new Parent();

            charles._name = “Chuck”;

 

            charles._children = new Person[] { andy };

 

            ellis._children = new Person[] { steve, charles };

            ellis._grandchildren = new Person[] { andy };

 

            Parent actual = (Parent)converter.Convert(ellis);

            Assert.AreEqual(“Andy”, actual.Firstborn.Name);

            Assert.Contains(actual.Siblings, steve);

            Assert.AreEqual(“Andy”, actual.FirstbornsName);

            Assert.AreEqual(“Ellis”, actual.Parents[0].Name);

        }

And, yes, I used some of my own family names for testing. And I crammed multiple tests into one for brevity.

The part of the design that made this painful before was my ElementInfo class. In the Reflection library, the PropertyInfo and FieldInfo classes are very similar, but their method signatures are slightly different to accommodate indexed properties. I wanted to avoid making this distinction throughout my code, so I created an Adapter class I called ElementInfo to provide the rest of my code a unified interface, exposing a GetValue(), SetValue(), and Type.

However, it turns out my ElementInfo class had two responsibilities:

  1. Make a distinction between a property and a field
  2. Act as an accessor for a type (that is, to get and set values)

As a result, it was hard to extend. So, I decided to separate the ElementInfo class into two. During this exercise, it dawned on me that properties and fields are collectively called accessors, which lit the way for me to redesign this part of the domain model.

It was the ElementInfo constructor that was determining whether an accessor was a property or a field, so its logic got moved to an AccessorFactory. I re-ran my test suite, and everything passed (it was all green).

Once I did that, ElementInfo just had that decision logic in its own methods. Remembering that my goal was to extend this class to handle more types of accessors, I extracted an IAccessor interface and made ElementInfo implement it. (I use ReSharper, so refactorings like this are largely automated.) I then used the “Use Base Type Where Possible…” refactoring, so that as much as possible, I wasn’t using my old ElementInfo class.

I then created Property and Field classes that implemented IAccessor, and reprogrammed the AccessorFactory to return Property and Field objects instead of ElementInfo objects. Re-ran the tests; all were green except the indexed property tests. So I deleted the ElementInfo class.

Now, I was in the position to create some new IAccessor implementations. The first I did was IndexedProperty, which you may recall that I had put into ElementInfo from last time. As I hoped, the only thing I needed to do to integrate it was add it to the Create() method on the AccessorFactory. Ran the tests; test suite still shows all green.

The first new implementation I needed was something I started out calling IndexableProperty, the idea being that it was a property whose type could be accessed with an indexer. However, it quickly became an ArrayProperty, because in my use case, the only examples of this are arrays. The analogous ArrayField followed shortly thereafter. With these in place, the Grandchildren[0] -> Firstborn mapping works.

What about Grandchild[0].Name? The engine doesn’t understand dot notation yet. So I created an AccessorComposite IAccessor that takes multiple accessors chained by dots. It splits the accessor string on the dots and calls the AccessorFactory on each fragment. Now the Grandchildren[0].Name -> FirstbornsName mapping works.

I still have a challenge ahead. The commented-out mapping, Name -> Parents[0].Name, still won’t work. When the AccessorComposite tries to set the value of Parents[0].Name, it fails because Parents hasn’t been initialized. I could create some code that would initialize the Parents array. If I did, the array of Parents would be { null }, and trying to get the value of null.Name doesn’t compute. I would need to have the array of Parents equal to { new Person() }, and then try to set that new Person’s name. For me, this is beyond the call of duty of an accessor representation!

I need to decide whether the user should explicitly populate Parents[0] before trying to set the name in the mapping, and if so how, or whether some other part of the engine should handle it. I’m leaning towards making it an explicit initialization, because having an array be null or empty might have meaning to the consumer of a converted object, and I don’t want to prevent the ability to return those special values.

Transforming arrays is a nice segue into some of the challenges of having to infer type information, which will be discussed in the next post.

Object Mapper: XML Parsing

2009 December 30

Recently, I’ve described the object mapper’s domain model and illustrated that it’s still evolving by discussing the “generation gap“. In this post, I talk about the components of the object mapper.

There are two main components to the object mapper. Since the mapper is configured via XML, clearly I need something to read in the XML and initialize the domain model. Because I’m constrained to C# 2.0, I used an XmlReader. To handle malformed mapping XML documents, I wrote an XSD schema and validate incoming XML before parsing.

Each node triggers the creation of a domain object. Each Source and Target is implemented with the Composite pattern as an Element. Sources are comprised of Targets, and Targets are comprised of leaf elements like property mappings.

Each component of the Element Composite exposes an Execute method that calls a Command. There are two sets of commands: one working on objects, the other on elements (properties or fields). For example, there is an ObjectSetter, that simply sets the target to the source. Correspondingly, an ElementSetter sets the target property value to the source property’s value.

Other types of Commands include an ObjectConverter, which invokes the conversion Function on the source and sets the target object equal to the result, and an ElementInjector, which sets a target element equal to a value specified in the mapping XML.

Array transformations are handled by way of a Decorator, which handles the invokation of the decorated Command on each element in the array.

Next post, I’ll talk about how I made some progress on bridging that generation gap.

Object Mapper: Generation Gap

2009 December 29

In yesterday’s post about the domain model, I described some of the use cases for the object mapper.

In trying to use it in a real-world situation today, my co-worker found another domain concept.

Let’s say I have the following hierarchy of objects:

  • Person { Name : string }
  • Parent { Children : Person[] } is-a Person
  • Grandparent { Grandchildren : Person[] } is-a Parent

Hopefully, that notation isn’t too hard to read. By that, I mean to say that a Person has a Name, a Parent is a Person with an array of type Person called Children, and a Grandparent is a Parent with Grandchildren.

Let’s further say that I want to use my Object Mapper to convert a Grandparent object into a Parent object.

To probe the problem, I created a new test class and started to write tests. I determined I’d need something like the following XML:

<Source ID="source1" Type="Grandparent">
<Target ID="target1" Type="Parent">
<Element Source="[TBD]" Target="Name" />
<Element Source="Grandchildren" Target="Children" />
</Target>
</Source>

The fly in the ointment is what to put in the [TBD] section. I want the name of, say, the first child.

However, even with all of the elements I introduced yesterday, I have no way of asking for elements of different “generations”, at different levels of the hierarchy. I have commands that can copy objects to objects and properties to properties, but not properties to objects or objects to properties.

Back to the TBD piece. It would be nice if it could read:

<Element Source="Children[0].Name" Target="Name" />

Children[0] is a C#-ish way of saying the first item in the array of Children, and the number is called the index of the array.

Of course, the test is red (i.e., doesn’t pass), because the Parent object doesn’t have a property called “Children[0],Name”. So far, so good.

This is really two problems in one. I decided to defer the issue of calling a property on a property (nested properties) by ignoring the Name part of the puzzle. So, I created an extra property on Parent called Firstborn, which I’ll try to populate like this:

<Element Source="Children[0]" Target="Firstborn" />

Failing test in hand, I applied myself to getting the test to pass. As I’ll explain more in a future post, I have an Adapter class that allows me to treat fields and properties the same called ElementInfo. It’s responsible for resolving properties, so I added support to the ElementInfo object to resolve indexed properties as well.

I re-ran my test. Still red.

After some debugging and head-scratching, I realized that what I really need is not support for indexed properties, but support for a property of a type that itself supports indexing, like Children which is an array.

To wit:

public Person[] _children;

 

// what I want to be able to extract info from

// example: mom.Children[0]

public Person[] Children

{

    get { return _children; }

    set { _children = value; }

}

 

// what I ended up supporting, oops!

// example: mom[0]

public object this[int index]

{

    get { return _children[index]; }

}

So, once more into the breach, dear friends!

I now return you to the scheduled posts in the series while I resolve this. The next post will talk some about the XML parser.

The Object Mapper Domain Model

2009 December 28

Last time, I introduced the object mapper. Here, I describe its domain model.

The request and response objects that require mapping are plain-old CLR objects with properties for the most part, though there are some arrays to contend with. The challenge is that the request and response objects do not have the same structure.

Many of the properties have a one-to-one correspondence. For example, a Name field on one request object may align with a Name property on the DataStore request. In some cases, though, the property names are different.

Other properties share a one-to-many association, so the contents of the source object must be copied to several target properties. And yet other pesky properties share a many-to-one association. For example, a Java application’s request might have address, city, state, and ZIP code as separate fields, but they must be combined into a single property of the DataStore request.

Here’s an example of a simple mapping document for a Foo object with Name and Age properties:

<?xml version="1.0" encoding="utf-8"?>
<Maps>
<Source ID="source1" Type="Foo">
<Target ID="target1" Type="Foo">
<Element ID="Name" Source="Name" Target="Name" />
<Element ID="Age" Source="Age" Target="Age" />
</Target>
</Source>
</Maps>

There is a Source, which describes a source object. That Source object can be converted into a Target object. Objects have Elements, which describe either properties or fields. Each element has its own source and target attributes to describe what property of the source corresponds to what property of the target.

So far, so good. Let’s say, though, that the source request object doesn’t define an Age property, but it’s required on the target request. For cases like this, I need the capability to inject a value:

<Source ID="source1" Type="Foo">
<Target ID="source1" Type="Foo">
<Element ID="Name" Source="Name" Target="Name" />
<Inject Target="Age">37</Inject>
</Target>
</Source>

The Inject node allows me to specify the value I’d like to inject, in this case any target object would have an Age of 37.

This poses a challenge, because that “37″ is a string by virtue of being XML. .NET doesn’t offer a way to implicitly make that “37″ into the number 37. So, I need a way to convert primitive objects, objects with no properties:

<Object Source="System.String" Target="System.Int32">
<Function Type="System.Int32" Method="Parse" />
</Object>

The Function node defines a method to invoke when converting the object. It’s a valid child of the Element node as well, so a property can be converted by a function as well.

Functions can refer to instance methods, which are called against an instance of a type. They can also refer to static methods, which belong to the type itself. One can even specify arguments, for cases like Substring where I might only want the first few letters of a string:

<Element ID="Name" Source="Name" Target="Name">
<Function Type="System.String" Method="Substring">
<Argument Type="System.Int32">0</Argument>
<Argument Type="System.Int32">3</Argument>
</Function>
</Element>

Sometimes, I may want to convert an array of one type to an array of another by converting each of its members individually by use of the ApplyToEachElement flag:

<Object Source="System.String[]" Target="System.Int32[]" ApplyToEachElement="true">
<Function Type="System.Int32" Method="Parse" />
</Object>

Here, the conversion engine will take an array of strings and convert it to an array of integers by calling int.Parse with each string as an argument.

That introduces most of the domain concepts of the object mapper. Next post will delve into the components that comprise the object mapper itself.