Dynamic Code Execution

  1. Dynamic Code Execution in VB.Net: A very useful tool to externalize the Rules  
  2. File: Module1.vb to test and run the Code  
  3. Module Module1  
  4. Sub Main()  
  5. Dim cCheck As New CodeCreate  
  6. Dim CarType As String = "CAR"  
  7. Dim CarMake As String = "TOYOTA"  
  1. Dynamic Code Execution in VB.Net : A very useful tool to externalize the Rules  
  2.   
  3. File: Module1.vb to test and run the Code  
  4.   
  5. Module Module1  
  6.   
  7.   Sub Main()  
  8.   
  9.     Dim cCheck As New CodeCreate  
  10.   
  11.     Dim CarType As String = "CAR"  
  12.   
  13.     Dim CarMake As String = "TOYOTA"  
  14.   
  15.     Dim CarYear As String = "2010"  
  16.   
  17.     Dim CarMile As String = "100010"  
  18.   
  19.     System.Console.WriteLine("Depreciation Rate of {1} {0} of YEAR {2} WITH {3} miles: {4}%", _  
  20.   
  21.                              CarType, CarMake, CarYear, CarMile, cCheck.GetDeprecRate(CarType, CarMake, CarYear,   
  22.   
  23. CarMile))  
  24.   
  25.     System.Console.ReadKey()  
  26.   
  27.   End Sub  
  28.   
  29. End Module  
  30.   
  31. File: IScript.vb (Interface)  
  32.   
  33. 'interface to generate script  
  34.   
  35. Public Interface IScript  
  36.   
  37.   Function CheckCar(carMake As String, CarYear As String, Miles As StringAs Integer  
  38.   
  39. End Interface  
  40.   
  41. File: CodeCreate.vb  
  42.   
  43. Imports System.CodeDom.Compiler  
  44.   
  45. Imports System.Reflection  
  46.   
  47. Imports System.Text  
  48.   
  49. Public Class CodeCreate  
  50.   
  51.   '' function that defines vb compiler environment and reference assemblies  
  52.   
  53.   Private Function GenerateScript(code As StringAs IScript  
  54.   
  55.     Using provider As New VBCodeProvider()  
  56.   
  57.       Dim parameters As New CompilerParameters()  
  58.   
  59.       parameters.GenerateInMemory = True  
  60.   
  61.       parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)  
  62.   
  63.       parameters.ReferencedAssemblies.Add("System.dll")  
  64.   
  65.       parameters.ReferencedAssemblies.Add("System.Data.dll")  
  66.   
  67.       parameters.ReferencedAssemblies.Add("System.Xml.dll")  
  68.   
  69.       Dim interfaceNamespace As String = GetType(IScript).Namespace  
  70.   
  71.       Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}  
  72.   
  73.       Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)  
  74.   
  75.       If results.Errors.HasErrors Then  
  76.   
  77.         Throw New Exception("Failed to compile script")  
  78.   
  79.       Else  
  80.   
  81.         Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)  
  82.   
  83.       End If  
  84.   
  85.     End Using  
  86.   
  87.   End Function  
  88.   
  89.   '' create script  
  90.   
  91.   Private Function createScript(myscript As StringAs IScript  
  92.   
  93.     Dim builder As New StringBuilder()  
  94.   
  95.     builder.AppendLine("Public Class Script")  
  96.   
  97.     builder.AppendLine("    Implements IScript")  
  98.   
  99.     builder.AppendLine("    Public Function CheckCar(carMake As String, CarYear As String, Miles As StringAs   
  100.   
  101. Integer Implements IScript.CheckCar")  
  102.   
  103.     builder.AppendLine("    dim retVal as integer = 60")  
  104.   
  105.     builder.AppendLine(myscript)  
  106.   
  107.     builder.AppendLine("    return retVal")  
  108.   
  109.     builder.AppendLine("    End Function")  
  110.   
  111.     builder.AppendLine("End Class")  
  112.   
  113.     Dim script As IScript = GenerateScript(builder.ToString())  
  114.   
  115.     Return script  
  116.   
  117.   End Function  
  118.   
  119.   '-- get the script  
  120.   
  121.   Private Function GetScript() As IScript  
  122.   
  123.     Dim ruleString As New List(Of String)  
  124.   
  125.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR<2010 AND (MILES/1000) <=10 THEN RETURN 20")  
  126.   
  127.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2010 AND (MILES/1000) <=10 THEN RETURN 10")  
  128.   
  129.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2011 AND (MILES/1000) <=10 THEN RETURN 9")  
  130.   
  131.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2012 AND (MILES/1000) <=10 THEN RETURN 8")  
  132.   
  133.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2013 AND (MILES/1000) <=10 THEN RETURN 7")  
  134.   
  135.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2014 AND (MILES/1000) <=10 THEN RETURN 6")  
  136.   
  137.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR>=2014 AND (MILES/1000) <=10 THEN RETURN 5")  
  138.   
  139.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR<2010 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 30")  
  140.   
  141.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2010 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 25")  
  142.   
  143.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2011 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 20")  
  144.   
  145.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2012 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 17")  
  146.   
  147.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2013 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 15")  
  148.   
  149.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2014 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 12")  
  150.   
  151.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR>=2014 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 10")  
  152.   
  153.     '--- more rules can be loaded from database  
  154.   
  155.     '-- and the rules can be separated into the classes for each type of vehicle   
  156.   
  157.     '-- with the use of OOP's polymorphism (Implementing Strategy Pattern)  
  158.   
  159.     Dim allRules As New StringBuilder  
  160.   
  161.     ruleString.ForEach(Sub(x) allRules.AppendLine("IF " & x))  
  162.   
  163.     Return createScript(allRules.ToString)  
  164.   
  165.   End Function  
  166.   
  167.   '' function to return depreciation  
  168.   
  169.   Public Function GetDeprecRate(CarType As String, carMake As String, CarYear As String, Miles As StringAs   
  170.   
  171. String  
  172.   
  173.     Dim ms As New CodeCreate()  
  174.   
  175.     Dim scriptEXEC As IScript = ms.GetScript()  
  176.   
  177.     If CarType = "CAR" Then  
  178.   
  179.       Return (scriptEXEC.CheckCar(carMake, CarYear, Miles)).ToString  
  180.   
  181.     End If  
  182.   
  183.     Return "UNKNOWN!"  
  184.   
  185.   End Function  
  186.   
  187. End Class  
  1. Dim CarYear As String = "2010"  
  2. Dim CarMile As String = "100010"  
  3. System.Console.WriteLine("Depreciation Rate of {1} {0} of YEAR {2} WITH {3} miles: {4}%", _  
  4. CarType, CarMake, CarYear, CarMile, cCheck.GetDeprecRate(CarType, CarMake, CarYear,  
  5. CarMile))  
  6. System.Console.ReadKey()  
  7. End Sub  
  8. End Module  
  9. File: IScript.vb (Interface)  
  10. 'interface to generate script  
  11. Public Interface IScript  
  12. Function CheckCar(carMake As String, CarYear As String, Miles As StringAs Integer  
  13. End Interface  
  14. File: CodeCreate.vb  
  15. Imports System.CodeDom.Compiler  
  16. Imports System.Reflection  
  17. Imports System.Text  
  18. Public Class CodeCreate  
  19. '' function that defines vb compiler environment and reference assemblies  
  20. Private Function GenerateScript(code As StringAs IScript  
  21.     Using provider As New VBCodeProvider()  
  22.     Dim parameters As New CompilerParameters()  
  23.     parameters.GenerateInMemory = True  
  24.     parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)  
  25.     parameters.ReferencedAssemblies.Add("System.dll")  
  26.     parameters.ReferencedAssemblies.Add("System.Data.dll")  
  27.     parameters.ReferencedAssemblies.Add("System.Xml.dll")  
  28.     Dim interfaceNamespace As String = GetType(IScript).Namespace  
  29.     Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}  
  30.     Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)  
  31.     If results.Errors.HasErrors Then  
  32.         Throw New Exception("Failed to compile script")  
  33.     Else  
  34.         Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)  
  35.     End If  
  36.     End Using  
  37. End Function  
  38. '' create script  
  39. Private Function createScript(myscript As StringAs IScript  
  40.     Dim builder As New StringBuilder()  
  41.     builder.AppendLine("Public Class Script")  
  42.     builder.AppendLine(" Implements IScript")  
  43.     builder.AppendLine(" Public Function CheckCar(carMake As String, CarYear As String, Miles As StringAs  
  44.     Integer Implements IScript.CheckCar")  
  45.     builder.AppendLine(" dim retVal as integer = 60")  
  46.     builder.AppendLine(myscript)  
  47.     builder.AppendLine(" return retVal")  
  48.     builder.AppendLine(" End Function")  
  49.     builder.AppendLine("End Class")  
  50.     Dim script As IScript = GenerateScript(builder.ToString())  
  51.     Return script  
  52. End Function  
  53. '-- get the script  
  54. Private Function GetScript() As IScript  
  55.     Dim ruleString As New List(Of String)  
  56.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR<2010 AND (MILES/1000) <=10 THEN RETURN 20")  
  57.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2010 AND (MILES/1000) <=10 THEN RETURN 10")  
  58.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2011 AND (MILES/1000) <=10 THEN RETURN 9")  
  59.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2012 AND (MILES/1000) <=10 THEN RETURN 8")  
  60.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2013 AND (MILES/1000) <=10 THEN RETURN 7")  
  61.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2014 AND (MILES/1000) <=10 THEN RETURN 6")  
  62.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR>=2014 AND (MILES/1000) <=10 THEN RETURN 5")  
  63.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR<2010 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 30")  
  64.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2010 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 25")  
  65.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2011 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 20")  
  66.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2012 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 17")  
  67.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2013 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 15")  
  68.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR=2014 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 12")  
  69.     ruleString.Add("carMake=""TOYOTA"" AND CARYEAR>=2014 AND (MILES/1000) >10 and (MILES/1000)<20 THEN RETURN 10")  
  70. '--- more rules can be loaded from database  
  71. '-- and the rules can be separated into the classes for each type of vehicle  
  72. '-- with the use of OOP's polymorphism (Implementing Strategy Pattern)  
  73.     Dim allRules As New StringBuilder  
  74.     ruleString.ForEach(Sub(x) allRules.AppendLine("IF " & x))  
  75.     Return createScript(allRules.ToString)  
  76. End Function  
  77. '' function to return depreciation  
  78. Public Function GetDeprecRate(CarType As String, carMake As String, CarYear As String, Miles As StringAs  
  79.     String  
  80.     Dim ms As New CodeCreate()  
  81.     Dim scriptEXEC As IScript = ms.GetScript()  
  82.     If CarType = "CAR" Then  
  83.         Return (scriptEXEC.CheckCar(carMake, CarYear, Miles)).ToString  
  84.     End If  
  85.     Return "UNKNOWN!"  
  86. End Function  
  87. End Class