I have an existing asp.net (c#) application. I need to provide users with a way to create flexibles rules to calculate an effective date given a hiredate and an enrollmentdate.
Some examples of rules that might be used:
- The later of hiredate or enrollmentdate
- HireDate + 90 Days
- The first of the Month after the enrollment date
- If the enrollment date is before the 15 of the month, then the effective date is the 1st of the next month. If it is on the 15 or after, it’s the 1st of the month after that.
I started out with a handful of offset fields (day offset, month offset, etc…), but as I come across new requirements, I’m coming to realize the current approach isn’t flexible enough.
What I would like to do is allow the end user to define a function that returns a date given two parameters (hiredate, enrollmentdate), and store that function in the database. When I need to calculate the effectivedate I’d pull this function out of the database execute it passing in the parameters to get my effectivedate.
My intial reaction was to look for a DSL that would allow me to define date manipulation functions and integrate that into my solution. However my search for an appropriate DSL has turned up nothing.
Now I am wondering whether CSharpCodeProvider might work as a component to the solution.
If I pull a string out of a database, and compile it via CsharpCodeProvider, can I enforce that the resulting code matches a function signature (takes 2 datetime parameters, and returns a datatime)?
Is there a way to ensure that the function doesn’t have any side effects? For example, No I/O. No reading or session, cache, or application.
See my recent answer here: Parsing "DateTime.Now"?
Essentially, you can easily leverage an existing library like FLEE to parse expressions and emit IL for these rules. If you take a look at the examples, you can see how to set up variables for the user expressions to leverage. For example, you may define a “rule” that consists of some input variables (like
HireDateorEnrollmentDate), and a user expression/predicate that returns the date. If you expose theDateTimemembers like I have in the linked answer, then users can leverage those as well.Just as a quick example, not tested but should give you an idea.
You can setup some custom functions to help, like getting the first day of a month:
A basic FLEE setup (you’ll have to customize/tweak as necessary)
Then your rules might look like: