Sharpen up: Generic object builder, reflection and dynamic objects (01 Pilot)

Antonio K
5 min readAug 11, 2019
“Human beings, it seems, are at their best when immersed deeply in something challenging. ” ― Cal Newport

After being peer pressured by numerous programming zealots I’ve decided to try running some sort of technical blog. Given the size of the community and low entry bar, Medium is, in my opinion, the obvious choice. (That and I don’t know how to set up my blog web page.)

Working in a vibrant environment sometimes leaves limited creative space for you to explore some topics. You usually should not be the guy who ends up writing a compiler instead of doing that task you were assigned about removing the shadow from the checkout button, however, this should not be interpreted as “stay in your comfort zone”. With that out of the way, I would like to allow myself to better explore topics I stumble upon while working my day job. (At night I dress up in the spandex costume and bring justice to people who test in production.) My goal is to have a series of posts dedicated to what I find interesting in the software engineering world or something that I’ve wanted to learn but never found time to do so. This will be more of a “learn as you go” style of writing instead of your typical Jon Skeet, comprehensive and definitive answer to all your problems style.

I hope my pun in the title will be excused.

Unit testing is the bread and butter of our craft and something that a lot of people disregard to bust out a feature or two more. I won’t go into detail why you should be doing though I recommend everyone put Roy Osherove’s The art of unit testing into their reading list.

Working on long term projects with gigantic scope requires setting up infrastructure for testing and once done, right will reduce your workload significantly. Luckily people smarter than us mortal engineers have already done the heavy lifting and we’re here only to reap the fruits of their labor.
One such tool is test object generator like NBuilder used for the generation of test objects in .NET but this concept is not tied to your language of choice. Fluent API makes object generation a breeze and added configuration options are delightful to use.

Here’s a basic example with the respective output:

A basic example of NBuilder usage
Output for the previous example

The first car has no name and it was first registered about two thousand years ago which, as I can imagine, will make its success on the used car market a bit troublesome. The second car, on the other hand, is brand new and it’s distinctive name and model will surely make it a hit once it reaches dealerships, however, it’s got no engine, yikes.

The builder can be configured to populate the object via the previously mentioned fluent API. You can give it a new engine and maybe even take off a few extra miles while you’re already there. Scaling this approach to chunkier POCOs is extra work which is borderline object initializers that exist since C# 3.0. More often than not this initialization is what you need, and added configuration serves you good when it’s needed to design objects for specific test cases.

Sometimes you’re not interested in the data itself, but rather the existence of data is what you’re testing for. If the test case was to check if it’s possible to put diesel into your EV you’d stumble upon slight annoyance and an old friend of mine: NullReferenceException. Despite the popular belief that money makes the world go round, it’s truly slight annoyances and mild discomfort that do so.

This seemed to me like a good opportunity to spend one afternoon to shave seconds off my setup phase of testing. Enter the Generic recursive object builder supported by NBuilder. The name sounds like I’ve just found a solution to the NP problem (CS degree is great for flexing as you can see based on my previous metaphor of choice).

Show me the code:

Source code can be found at https://github.com/pavisalavisa/SharpenUp01

The basic idea is to take any class and build a graph with the desired depth using NBuilder as a backbone because it already does such a good job. If in the future NBuilder starts supporting this behavior out of the box, this snippet will be obsolete because there’s no way that something written in two hours can be as potent as something developed for production use. Nevertheless, it’s a great opportunity to get a sense of how it might be done and to dig a bit deeper into reflection, generics, recursion and dynamic objects.

The main problem that had to be tackled was ensuring generic behavior in the runtime which is where reflection comes into play. This can be a risky business so encapsulating this behavior is not a bad idea, however, you should be aware of performance implications reflection has on your program.

Builder iterates through properties and based on the type and current depth builds complex type and assigns it to the property. The reason I kept track of depth is because of circular references which would cause stack overflow due to recursive builder calls. When the desired depth is reached or there are no complex types in the current step of building for the given type, the actual build phase can take place.

Dynamic objects are not something that should be practiced in the OOP world and truly, you won’t be using them much once you’ve embraced the OOP paradigm. I’ve had an opportunity to use a dynamic object in this example, and although it could’ve been avoided, I think that it makes for an elegant solution. The problem is that both list builder and single object builder have the Build method exposed on their interface, but those are two different interfaces. You could argue that this violates the Interface segregation principle and that both interfaces should inherit from the Buildable interface that would only provide build functionality to the client code. Dynamic objects allow you to use the knowledge you have superior to the compiler and allow these nuggets to make your code more readable and/or fragile.

Dynamic objects were of no use when recursively building lists of objects. The runtime does not allow you to assign ICollection<object> to the type of ICollection<Car> and this is perfectly reasonable given the information at hand. This is where I sneaked in my extension method ListOf which performs cast that is not known at compile-time and through the magic of boxing mechanism makes the assignment possible. Here’s that hazardous piece of code:

Handle with care

Finally here’s the example:

Example in contrast to previous solutions
Output for the previous example

This output might be lengthy but I feel that it drives home the point about how much setup you’d have to perform to achieve this behavior manually. Plus you’ve now got a full list of owners and it will probably help you bring the price down a couple of hundred.

Most of the details were left out to be as concise as possible. Source code can be found at https://github.com/pavisalavisa/SharpenUp01

I hope that putting a number and announcing a series of posts will make me commit to writing and allow me to learn something myself if not teach others about various topics.

--

--