Monday, October 18, 2021

Obfuscar + NVelocity + anonymous types = issue

Some time ago I faced with interesting issue related with Obfuscar and anonymous types used with NVelocity template engine. If you use NVelocity for populating templates then your code may look like this:

string Merge(string templateText, params Tuple<string, object>[] args)
{
    var context = new VelocityContext();
    foreach (var t in args)
    {
        context.Put(t.Item1, t.Item2);
    }

    var velocity = new VelocityEngine();
    var props = new ExtendedProperties();
    velocity.Init(props);
    using (var sw = new StringWriter())
    {
        velocity.Evaluate(context, sw, "", templateText);
        sw.Flush();
        return sw.ToString();
    }
}

Here we pass templateText itself and tuple(s) of (key, value) pairs where key is string name of parameter used inside template (like $p) and value is object which has to be used for expanding this parameter to the real string value in resulting text (e.g. if you have "$p.Foo" inside template then pass object which has "Foo" string property set to "bar" value - then "$p.Foo" in template will be replaced by "bar").

For objects passed as parameters into this method anonymous types can be used - it is very convenient:

string text = Merge("My object $p.Foo", Tuple.Create("p", new { Foo = "bar" }));

If you will run this code as is it will return "My object foo" which is correct. But if you will try to obfuscate your code with Obfuscar then you will get unexpected result: instead of expanded template you will get original template text "My object $p.Foo" i.e. template won't be expanded to string.

The reason of this problem is that Obfuscar by default removes properties of anonymous types - there are issues about that: Anonymous class obfuscation removes all the properties or Anonymous Types. In order to solve the problem you need to instruct Obfuscar to not obfuscate anonymous types:

<Module file="MyAssembly.dll">
  <SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" skipStringHiding="true" />
</Module>

After that anonymous types won't be changed and NVelocity templates will be populated to string correctly.

No comments:

Post a Comment