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.
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.
In my last work-related post, I described (the transition from my old workplace to my new one. In it, I briefly mentioned the project I’m working on. In an upcoming series of posts, I’ll highlight some of the technical challenges I faced while creating the object mapper service.
First, let me describe the object mapper service. Out there somewhere in the company, there exists a handful of Java applications that interface with a legacy application to get some data. That data is now also exposed by a .NET application I’ll call the DataStore, so the goal is to retire the legacy application.
To do that, we’re putting in place a .NET web service written in C# 2.0, which will accept requests from each of those Java applications. It takes the request, convert it to a DataStore request, execute the request, and then take the DataStore’s response and convert it back into a response object that Java application can consume.
Most of the work of the web service is accomplished by passing messages from the Java application to the DataStore and back. However, the web service does need to convert requests and responses. Hard-coding the web service to do that would introduce some unwanted dependencies on the Java applications and the DataStore. Any time one of their requests or responses changed structure, the web service would need to change as well.
Instead, I’ve created a component that uses an XML document that describe how to map objects of one type to another to drive the conversion process. This is the object mapper.
The next post will describe the domain model of the object mapper.
I didn’t know quite what to expect when my belle and I attended Too Hot to Handel recently. We were in for an unforgettable experience!
The piece was conceived and conducted by the Colorado Symphony Orchestra’s conductor laureate, Marin Alsop. It’s a brilliant interpretation of Handel’s Messiah as a blend of classical, gospel, and jazz.
Woodwinds give way to a piano, organ, and electric guitar. The violins sit to Ms. Alsop’s left, a contingent of saxophones wait behind the organ, to her right sits the brass section, and to her far right lie the violas and cellos. Before her sit three vocalists: a soprano, an alto, and a tenor. And, being Handel’s Messiah, behind the orchestra is a full choir.
Ms. Alsop clearly enjoys this piece tremendously, and it shows with her almost conspiratorial relationship with the audience. She is obviously in full control of the ensemble, but she makes it look a scene in a movie where an actor imagines beautiful music and in the background, musicians furiously work to make her whims come alive. Ms. Alsop, you are truly a joy to watch.
Even though the subtitle of the work is “A Gospel Messiah”, the music struck me as jazz. The melodious scatting of the tenor Thomas Young contributed, I’m sure, as did the amazing sax, piano and drum solos.
The choir did a fine job augmenting the orchestra. And let there be no doubt that the mezzo-soprano Vaneese Thomas and the soprano Cynthia Renée Saffron brought gospel to Boettcher Concert Hall that night!
Perhaps my only regret is that the balance was off in places, where it seemed that the choir drowned out the tenor more than they should have. I also found seemingly random arrangement of their choir robe styles distracting at times.
Truly, we were transfixed throughout the whole performance. I would heartily recommend this concert to anyone with an interest in Handel’s Messiah or new interpretations of classical works!
I embarked on an adventure last month, leaving my old job after eighteen months to re-enter the world of consulting.
When I started at the old firm, I thought of myself as just a computer programmer. I had reached a plateau at the home-building firm where I’d cut my teeth and had arrived at that position ready for a new challenge.
The first week, I was asked to add an enhancement to an application I hadn’t seen before. They wanted the capability to alter an HTML control’s text via an XML configuration file. I turned it around quickly, and developed a good reputation.
It turned out that the department had just started using agile and were having trouble getting over the hump. At my prior position, we’d been doing Scrum for a while and I said I could get it going there. They gave me a team of eager people and we were wildly successful. We got the rest of the department on Scrum, and our department managed to nearly double our output. I became a key part of the team, someone whom management and fellow developers looked to for leadership.
Sadly, it was not to last. We sold our product to a large customer overseas, and we were not ready to support that customer as though the product were a custom application. Meanwhile, the company I worked for had been acquired just as I hired on, and this overseas deployment brought scrutiny and change from the main office. As their culture and decisions supplanted our office, our agile ways and product vision met with more resistance.
I believe that friction led to some key leadership departures, and the magic that dwelt in that place dwindled away. I was even given the role of lead architect, but I quickly came to realize it was a quixotic quest and one not to be combined with a promotion. So, I sought my fortunes elsewhere.
My current position is a stark contrast to my architect position. My sphere of influence went from office-wide to cubicle-wide overnight. Most of my co-workers work in another state, and I feel isolated from the people I work beside.
The work is somewhat different from what I expected, too. I imagined technical challenges in decommissioning a certain piece of legacy middleware and replacing it with an adapter web service. We started by building a mapper service that can convert a type to an arbitrary type driven by an XML specification, for use on request and response objects.
A week in, I realized I was building something akin to ObjectBuilder or an IoC container. The constraints of the project hampered some tasks. For example, I had to fight to use unit tests, and I was asked to deliver a solution without any third-party libraries such as MbUnit. I was limited to VS 2005, C# 2.0, and ASMX web services.
I did have some latitude, though. I architected the whole solution. In the beginning, I though I was going to have to implement my own version of LinqBridge, but I found that the Composite and Decorator patterns led to some simple structures with powerful functionality.
I used TDD and ReSharper to amaze my co-worker with my quick delivery and robust code. My tests are in MbUnit, and I’m glad to report that during the development effort, the solution never dipped below 90% coverage as reported by PartCover. Initially, I didn’t have access to their source control (VSS), so I installed Subversion locally and used Tortoise SVN to write to a repository on my network drive, which is where my tests still safely reside.
Sadly, though, I did not run into the kind of design challenges I was hungry for in building this component. However, I must say that I’ve leveraged the Reflection library much deeper than I had before. The most interesting piece was conditional mappings, which I implemented as delegates.
Going forward, it looks like I will be doing analysis of their legacy Java systems, detailing their old object and data models. Once done, systems analysts will be able to map the legacy application to the new infrastructure, and we can create an adapter web service with the help of that mapper component we wrote.
Just a quick note wishing you and yours a happy Thanksgiving!
I give thanks to my wonderful friends and family for their love and support, for my health and job, and for unknown blessings already on their way!
It’s been some time since I’ve written. I’m in the middle of some pretty large life changes. I’m in the middle of divorce proceedings. On top of that, I’m changing jobs.
My employer had been an independent software shop. It was bought by a big financial giant right before I was hired on. Recently, a lot of the old guard management left, leaving the big giant management to fill the void. There has been a large culture shift for our little agile company doing distributed systems work going into a mainframe, brick and mortar style world.
My last project as an employee for them is to produce an internal presentation on PCI compliance and the OWASP Top 10 vulnerabilities and how they apply to our application. There is a wealth of information on security vulnerabilities, that’s for certain! While researching the presentation, I was surprised to learn about the number and quality of the tools that exist for probing applications.
Monday, I’m dipping my toes into the consulting waters for the first time. I’ve taken a gig with a consulting firm I’ve worked with before. I’ll be filling a position at a large network bandwidth provider, writing software to integrate their systems. In theory, it’s a step up, though it can be hard to tell with the different styles of compensation. I’m looking forward to reporting about it in future posts.
What’s up in your world?
In a previous review of Miyazaki films, I mentioned I hadn’t caught a couple.
Last week, Netflix delivered Porco Rosso. I enjoyed it a lot! The kids did too.
What impressed me most about Porco Rosso wasn’t the plot or the telling of the story, both of which were very familiar after having watched the others. Mr. Piccolo, whose family helped repair Porco’s plane, reminded me strongly of the Boiler Man from Spirited Away, for example.
As I watched the film, I kept thinking how it would make a wonderful backdrop for a Spirit of the Century campaign! The setting reminds me of the Xbox game Crimson Skies, a nation of islands connected by plane and zepplin. The characters are pure pulp. Porco would make an excellent Centurion, a Superb pilot. Gina, the restaurant owner with Support Rapport and Great Contacting. And so on.
In a side note, this is my 100th post. The blog has been a pleasure. It always amazes me to see what posts people are drawn to.
Some posts of note have been:
- Spirit of the Century first session impressions as well as one about Spirit of the ‘Verse, my Firefly adaptation
- iPhone application mini-reviews
- What if Edison hadn’t invented the light bulb?
- my answers to a couple Code Katas
- a workaround for a common StarTeam 2008 Cross-Client startup issue
As you can see, my readers are a diverse bunch. Part of me want to focus the blog on a particular subject, but no one subject dominates my readership.
Any requests? What would you like to see in the next 100 posts?
Last week, the City saw fit to hire me as a taekwon-do instructor. Tonight was my first class teaching.
read more…
My oldest son has joined the crew as a lycanthropic species. We’re still working on his stats. He’s an engineer named W’an.
The kids love the concept of LARP, so that’s what it became. We didn’t get a lot accomplished in the session. Honestly, that’s okay — we had a great time, and that’s what counts!
We left off last session with a crew exchange to prevent trickery. The three player characters were the team Starfleet selected to travel aboard the Goodnight-Loving. W’an slowly gained the trust of the pirates as things started mysteriously malfunctioning.
Gorm the Klingon tried to bully the pirates into leaving them alone so they could roam the ship freely — no go. Finally, W’an engineered a radiation leak in the cargo container they suspected carried the planet buster bomb and convinced the pirate left in charge to jettison it in an escape pod. The Ayrton tractored it into their cargo bay. Mission accomplished!
Our Vulcan XO/medic Vanisha didn’t have much to do, and my daughter and I talked afterward about creating dramatic situations. I suggested, for example, that she could engage the other characters in some leading dialogue. Or that she improvise something similar to the way my oldest did with the old freighter’s engines.
Things really got fun when I suggested to my son that he dig out some props I’d made out of LEGOs in my youth. They really helped the kids get into character!
One portion of play was particularly funny, in which W’an called the captain of the Ayrton on a LEGO communicator and said, “Someone set us up the bomb!” I whipped my head around and said, “What you say?” The four of us immediately riffed into Zero Wing and recited the entirety of ALL YOUR BASE ARE BELONG TO US, which the kids know from the Laziest Men on Mars song. It took us several minutes to stop laughing and get back to roleplaying!
The money moment of the session happened when my daughter said, “Hey guys, instead of sitting on our butts all day, we could roleplay Star Trek!”
The defense rests.



