0

I'm working on a C# project which provides users an on-demand method of importing data from various formats and then performs mail-merge-like actions to complete a template. The process works for basic data types. However, I need to add the ability to perform calculations on the existing data (which is not present in the source) so the results can be placed on the output.

Example 1:
Date range -- if there is data in both the start date and end date fields then the output should contain the two dates separated by " - ". If only one is present then just that date is output.

Example 2:
Conditionals -- if data in field X meets criteria Y then output Z.

Example 3:
Format text before conversion to number and format output as currency.
Source Field: "000059975"
Desired Output: "$599.75"
Note that the text version of the number was of fixed length and included both whole and partial units of currency (dollars and cents in this case).

I understand how to perform these actions in code; however, all configuration of the data sources and the "calculated" fields must be done at runtime via strings. All data, once imported, is placed in a DataTable, so any solution will have access to the capabilities thereof in C# 4.

Some ideas I've considered so far:

  • lambda functions with a regex replace
  • direct C# expressions
  • scripting language (e.g., SQL / JavaScript / Python) processing
  • A DSL (though I have no experience with designing/implementing such)

I've not successfully identified a way to implement any of the above possibilities. Note also that while this is an internal business application which will largely be used by a small group of IT staff, I'd prefer to stick with a solution which limits the possibility of arbitrary code execution.

What techniques exist to address this need?

4
  • How do your template descriptions look like? Simple text files with some placeholder mechanism? Can you give an example?
    – Doc Brown
    Aug 15, 2013 at 14:58
  • The templates vary (some are HTML, others plain text, other PDFs, others Microsoft Word documents). In all a name/placeholder is used. For example, in text documents it's usually something like [LastName] whereas in PDFs and Word documents the name is an attribute of a field. Getting the information from the DataTable to the template works fine. I need to add additional fields to the DataTable (which I can also do just fine) -- but those fields need to be calculated with a user-editable definition.
    – Gnosian
    Aug 15, 2013 at 16:01
  • Strings can be converted to numbers at runtime. I don't see anything here that requires an "eval" function or any of your proposed bullets. You haven't said much about what your "conditionals" look like, or whether any of these data points contain equations that need to be evaluated. Aug 15, 2013 at 16:09
  • Those were just simple examples. The actual needs of each calculated field cannot be determined at compile time -- they have to be configurable and extensible through the UI during runtime. Performing the changes to #3 are trivial in code -- but I need a way of defining that code at runtime and then executing it (much as how LINQPad evaluates and runs code).
    – Gnosian
    Aug 16, 2013 at 14:11

1 Answer 1

0

It appears that there are a few possible solutions:

  • Reflection -- Reflection.Emit
  • CodeDOM -- System.CodeDom
  • Expression -- System.Linq.Expressions.Expression
  • CSharpCodeProvider -- Microsoft.CSharp.CSharpCodeProvider

Edit
CSharpCodeProvider ended up being the most straightforward solution. I used the technique detailed at Treating C# Like A Scripting Language and it worked perfectly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.