I’m toying with a class that will allow for efficient token replacement at runtime.
Why re-invent the wheel?
A bare class that does just this is rare.
Absent a class like this, people just use all kinds of string manipulation techniques that can be slow and sluggish.
What am I out to solve?
Let’s say your website supports some notion of a CMS. So you let some users publish pages / content by filling in a form and storing the content in the db. Next usually comes the request that special variables can be planted in the content. This includes ads, formatting, dynamic links, personalization data etc. The first reflex is to just use string replacement. But if the content is not the whole page, the tendency is to assign the string to a literal or somehow just create a string field in your page and then assign it to some code in front control. The issue with this is that at the very best, the input string (template) is scanned every time in order to determine where the token markers are. At the very worst this is combined with string thrashing and ends up being a wasteful string concatenation exercise. Me thinks a factory class TemplateFactory can generate an immutable template class. That class can be cached for a long time. The template innards would all be private and hidden. They would consist of all the static parts and all the “holes”. The template will be in itself a factory, letting a user get an instance of a RuntimeValue object. The runtime value object will support a
.Add(TokenName, TokenValue) method, which would check the token names and be bound to the originating factory (the template that created it). This way, you get some runtime checking of invalid token assignments. The template would expose a method Render(writer, runtimeValues) . The render method would be the one merging the template with the runtime values. Notably, there would NOT be a string MergeValues(values) call. That’s because strings are immutable and storing the merged string at any scope is a waste. The only reason one would need to store it is for later use in a stream context (IIS response stream, mail message, file etc).
If this pains anyone, the use of
StringWriter is recommended. But the intended use of this scheme is to plant the
Render() call somewhere in the
OnRender() event equivalent of your application. The idea is that the object would both enforce a correct (IMHO) deferral of merging to the presentation time, and implement an efficient algorithm for fast merges. The instance creation is going to bear the grunt of parsing the template and scanning for token markers. If a CMS system is the target app, it can pre create these runtime objects and keep them in memory. A template object would specifically NOT be created each time you need to merge. Only the lightweight
RuntimeValues need to be gotten from a factory and populated each time, because these are the real runtime instance variants. The rest of the template is “static”.