SYSK 293: Business Rules – Easy, Flexible, Decoupled

From what I see, in this version, Microsoft Windows Workflow Foundation doesn’t allow you to author and use business rules without a link to an activity or a workflow…  Also, the types of rules you can create are somewhat limited…  After spending some time trying to fit WF into what I needed, I recalled the simplicity of the Microsoft ScriptControl object that allowed you to run VBScript or JavaScript code snippets, and even allowed to pass in parameters…


I wanted to have a mechanism where I can execute a .NET code snippet that was not previously compiled with the simplicity of the following statement:


ScriptEngine.Evaluate(codeBody, methodToInvoke, methodParameters);


So, I decided to create a class that can compile and run C# code on the fly…  Imagine being able to create your business rules in C# (or VB.NET), maintain them in some secure but easy to edit place like database, and execute them when needed… 


Here is my code (as always, use at your own risk, etc…):


using System;

using System.Collections.Generic;

using System.Text;


namespace YourCompany.YourProject


    public class ScriptEngine


        private static Dictionary<long, CachedCode> _cache = new Dictionary<long, CachedCode>();


        public static object Evaluate(string code, string methodName, object[] parameters)


            object snippetInstance = null;

            System.Reflection.MethodInfo method = null;


            // Did we already execute this code before?

            long hashCode = code.GetHashCode();

            if (_cache.ContainsKey(hashCode))


                snippetInstance = _cache[hashCode].SnippetInstance;

                method = _cache[hashCode].Method;




                string codeToExecute =

                    “using System;” +

                    “public class CodeSnippetWrapper { “ +

                    code +



                Microsoft.CSharp.CSharpCodeProvider cp = new Microsoft.CSharp.CSharpCodeProvider();

                System.CodeDom.Compiler.CompilerParameters p = new System.CodeDom.Compiler.CompilerParameters();


                p.GenerateExecutable = false;

                p.CompilerOptions = “/t:library”;

                p.GenerateInMemory = true;


                System.CodeDom.Compiler.CompilerResults cr = cp.CompileAssemblyFromSource(p, new string[] { codeToExecute });

                if (cr.Errors.HasErrors)


                    StringBuilder sb = new StringBuilder(64);

                    foreach(System.CodeDom.Compiler.CompilerError e in cr.Errors)





                    throw new ApplicationException(“Errors in rule “ + methodName, new object[] { sb.ToString() });



                System.Reflection.Assembly assembly = cr.CompiledAssembly;


                snippetInstance = assembly.CreateInstance(“CodeSnippetWrapper”);


                method = snippetInstance.GetType().GetMethod(methodName);


                // Cache it for the future

                _cache.Add(hashCode, new CachedCode(snippetInstance, method));



            return method.Invoke(snippetInstance, parameters);



        private class CachedCode


            private object _snippetInstance = null;

            private System.Reflection.MethodInfo _method = null;


            public CachedCode(object snippetInstance, System.Reflection.MethodInfo method)


                _snippetInstance = snippetInstance;

                _method = method;



            public object SnippetInstance


                get { return _snippetInstance; }



            public System.Reflection.MethodInfo Method


                get { return _method; }








Comments (5)

  1. El G says:

    For scripting I prefer using LUA with LuaInterface for .NET integration.

    Is a much easier language for business rules scripting and is easily expandable, while the footprint is less than half a meg.

    Just a thought.

  2. Sean.McLellan says:

    Check out the Dynamic Code Activity on

    What good is a business rule if you don’t have some condition based on it, and what if you could declaratively state what happens based on the results when that business rule is evaluated? Welcome to WF.

  3. rseroter says:

    Hey Irena,

    Actually, you can do WF rules outside a workflow.  I did a demo of that at the SOA Conference last fall … Not a bad solution.

  4. irenak says:

    Let me try to make it clear:  as I understand it, to create rules in xaml using an authoring tool like one provided in Visual Studio Extensions for Windows Workflow Foundation, one has to first create an activity or a workflow.  You could instanciate and run rules independently after that — and there are samples on netfx3 that demonstrate that…  

  5. Austin says:

    Actually you don’t need an activity to create rules nor do you have to run the rules against any activity. Any object will do, but you have to instanciate the RuleSetDialog yourself:

    RuleSetDialog ruleSetDialog = new RuleSetDialog(typeof(yourClass), null, null);