-2

We have a system with many logic expressions, they're implemented as series of boolean functions operating on variables and the rules are stored as XML. As the XML files are compiled into the assembly as resources, they don't change. For performance and extensibility reasons, it's been asked if we could pre-compile the rules.

The logical steps would be read XML -> generate C# expressions -> add expressions to rule class(es) -> add generated classes to application -> replace existing 'expression parse, return value' with call to method in the generated class.

The language is C#, but I'm hoping there's a pattern or similar for this so I can do some research. Even better if there's a config file format or approach that exists to do this.

I've used logic-less template handlers in the past - https://github.com/Handlebars-Net/Handlebars.Net and this in some ways is the opposite, a logic full template handler

5
  • Instead of xml, you can use JavaScript to store your rules and you can use YantraJS (Disclaimer I am the author) to interact with your C# code. YantraJS also has an expression compiler, however I would recommend using JavaScript for better clarity, unit testing etc. Commented Aug 13 at 3:53
  • 3
    Don't fall for the "inner platform" anti-pattern. IMHO translate the expressions to C#, add the C# code to your source control system, then delete the xml completely. Commented Aug 13 at 5:06
  • 1
    If your purpose is to support runtime configuration, then you can inject the expressions into C# and use the Roslyn compiler to execute the expressions at runtime. There are lots of .Net expression evaluators available, so the real question is why you didn't search the web first? If you have a specific expression format that you are struggling with or a specific expression engine then you can post about it on SO, but this post is currently just seeking for advice on choosing software, which puts it out of scope. Commented Aug 13 at 5:58
  • 1
    Why not just rewrite the rules with C#? You said they don't change anyway. Commented Aug 13 at 9:29
  • I don't understand the "performance" argument; the parsing and compiling can be done at "start-up". In terms of extensibility, I started with an app that parsed csv files, on demand. I'm now adding a "binary" option: parsed and binary versions of said csv files. The csv files are published monthly by a third party. The binaries are a moving target but improve start-up times; once converted. Commented Aug 13 at 23:12

1 Answer 1

1

I would recommend to look into writing a source generator:

A Source Generator is a new kind of component that C# developers can write that lets you do two major things:

  • Retrieve a Compilation object that represents all user code that is being compiled. This object can be inspected and you can write code that works with the syntax and semantic models for the code being compiled, just like with analyzers today.
  • Generate C# source files that can be added to a Compilation object during the course of compilation. In other words, you can provide additional source code as input to a compilation while the code is being compiled.

Basically you write a C# code which will generate C# classes based on some files in the project and then add it to the target project:

<!-- Add this as a new ItemGroup, replacing paths and names appropriately -->
<ItemGroup>
    <!-- Note that this is not a "normal" ProjectReference.
         It needs the additional 'OutputItemType' and 'ReferenceOutputAssmbly' attributes. -->
    <ProjectReference Include="path-to-sourcegenerator-project.csproj" 
                      OutputItemType="Analyzer"
                      ReferenceOutputAssembly="false" />
</ItemGroup>

See more:

Another option is to use T4 Templates which for example is used by EF Core for customization of reverse engineered model generation.

Sign up to request clarification or add additional context in comments.

2 Comments

OP's issue is more about runtime configurable expressions, T4 and SourceGenerator are compile time solutions.
@ChrisSchaller "As the XML files are compiled into the assembly as resources, they don't change" - from the OP. I know that those solutions are compile time, based on the information provided I thought that the question is exactly compile time hence the answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.