allBlogsList

Choosing Between Weakly and Strongly Typed Properties in Sitecore Commerce

Commerce Server allows to extend object properties in two ways: using weakly and strongly typed extensions. Sitecore Commerce Connect in turn follows the same pattern. Although the syntax is a bit different in Commerce Server. For weakly-typed properties we simply populate a key-value collection; the first example below is using the Commerce Server syntax, while the second one is for Commerce Connect 0 –

myOrder[“CustomProperty”] 

Commerce Connect

myOrder.Properties[“CustomProperty”]

On the other hand to add strongly-typed properties we can extend the base Commerce Server and Sitecore Commerce Connect models using inheritance and configuration updates.

Deciding Between Strongly and Weakly Typed Properties in Sitecore Commerce

When I first ran into having to choose one or the other, my inner architect astronaut was preparing for a long journey to the theoretical land of standards and recommended practices; however, the answer did not come from research, but rather from trial and error.

The traditional wisdom of development states that we want to stay away from magic strings as much as possible, which is a hit on the weakly-typed properties. In the weakly-typed world, unless we create constants and extensions methods, we run the risk of a lot of quoted text in our code, which is of course, prone to human error, lacks compile-time validation and could be full of runtime surprises.

Another significant disadvantage of using weakly-typed properties, is in the name. Unless you have control over the input and persistence layers, there is no telling what type is going to end up in the magical object value property, making type conversion occasionally tricky in addition to the same issues, as with the weakly-typed properties.

Training and code knowledge – this is sort of a big one for me. I can mitigate the magic strings and lack of type definition by creating extension methods for getting and setting properties, however, unless developers are properly trained on how to use them, or literally know what custom properties exist, there is no easy way of finding that out. The intelligence in Visual Studio will not help in this situation and unless you are creating extensive integration and unit tests, errors caused by weakly-typed properties can be very hard to catch, and the more frequently these properties are used – the higher the risk.

At this point it seems like a no-brainer – let’s use strongly-typed properties! According to the "book of reason" this makes absolute sense – we can do compile-time validation, we now have type safety, and there is less code to maintain overall.

To do proper due diligence we turn to Sitecore and Microsoft documentation for creating strongly-typed properties. The process is very much same at the high level – create a new model, inherit the original base type, add new properties and update mapping configuration. Commerce Server requires a bit more configuration updates in addition to the database schema changes (ouch!), however, it still seemed manageable. There are plenty of tutorials and walkthroughs on customizing Commerce Server types, so that was not going to be a problem.

The Sitecore side of things also did not look bad, as per documentation the configuration updates of the entity nodes need to point to the new types - all that was documented. One can then reasonably assume that Sitecore factory would properly instantiate our new type when it’s being called on.

It looked like it was a bit more work to setup the strongly-typed properties, however, the additional overhead was not outweighing the costs in my book. Onward with the strongly typed fields!

If this was a movie, you would now hear a record scratch, and a voice in the background say something along the lines of “…and this is where I took the wrong turn.”

The Underwater Rocks of Strongly-Typed Properties

On one of the recent projects we were tasks with extending multiple Commerce Connect and Commerce Server types with custom properties. Using the reasoning above we bravely recommended using strongly-typed properties. In our mind we would simply create the new types and update a few configuration file entries to point to our new classes and done deal.

Everything went well at first - we created the new types and patched the Sitecore configuration, however, only to discover that our types were not being properly used. We debugged our code and saw the default base Sitecore Commerce Connect types being passed around. So, we started digging. The first problem we found was that the way types were being created was trough passing a type in the argument –

EntityFactoryExtensions.Create<commercecartproduct>(this.EntityFactory, "CartProduct");
</commercecartproduct>

To break this line down, we are requesting a new object creation from the type specified in configuration with the a given node name. You may have already caught the problem – the Commerce Connect and Sitecore Commerce Server Connect layer casts the type into the base type, which removes all the custom properties!

After crawling through the Sitecore Commerce libraries we also noticed the use of explicit type names used in casts and conversions.

Our knee-jerk reaction was to replace those lines with our new types, so we went on the ultimate processor patching spree – we would look for references to the base type we overwrote and replace the processors and request and response objects with our new classes. Things were going well at first and everything seemed optimistic, until we started running into issues with type conversion due to inheritance conflicts and inability to overwrite properties. We found ourselves patching more and more processors, adding tens of new code files to our customization project, when we paused and did a sanity check. We realized that we were pretty much rewriting the Commerce Connect and Sitecore Commerce Server connect layers! The code was so closely coupled that ad-hoc updates were almost non-existent, a single update would trigger a chain of updates, where each one would do the same in turn. If we wanted our custom properties to be available everywhere – we had rewrite most the commerce layer.

Choosing Weakly-Typed Properties

Beat up by long nights of hopeless patching we turned back to weakly-typed option. After the nightmare we went through with the strongly-typed properties, the disadvantages of the weakly-typed ones felt very insignificant, in fact in a matter of few hours we implemented the same customizations that would have taken us days and potentially weeks, including testing, using the strongly-typed properties.

strongly vs weakly typed

It was clear to us that weakly-typed properties were the way to go for Sitecore Commerce customizations. It is still possible to customize bits and pieces of Sitecore Commerce with strongly-typed properties easily, however, those are very isolated areas. It feels like someone had the right idea, but over time as the Sitecore Commerce Server Connect layer was growing, the development go a bit relaxed and the abstraction rules were not properly followed and processors and pipelines were developed in a boxed environment without being a good neighbor to others.

Weakly Typed Properties and Type Extensions

Once we started going down the road of the weakly-typed properties, we quickly realized that something had to be done to mitigate the damage. Earlier I mentioned extension methods, which could help with “type-safety”, and that is exactly what we created.

We created two extension methods for each custom property – a getter and a setter in the following fashion for a custom Memo property of the Cart object –

public static string GetMemo(this CommerceCart cart)
{
var memo = cart.Properties[Constants.CommerceCart.MemoPropertyName] as string;
return memo;
}
public static void SetMemo(this CommerceCart cart, string memo)
{
cart.Properties[Constants.CommerceCart.MemoPropertyName] = memo;
}

Now all we had to do is make sure we used these abstraction methods everywhere we needed to reference the Memo property. Is it pretty? – definitely not, but it mitigates the risks added by weakly-typed and does the job, which is sufficient.

Stay With Weakly-Typed Properties

So what is the recommended approach? – Unless you are making extensive, frequently used and large long-lasting customizations (yes, the stars do need to align here), I would recommend to calm your inner architect astronaut and stick with the weakly-typed properties. On the other hand, unless your company tends to fall behind in technology, these customizations won’t likely have a long shelf-life as Sitecore is deprecating Commerce Server in favor of the new shiny Sitecore Commerce Engine soon.