Fixed dynamic object support when using RuleParameter (#33)
parent
c82576e4ee
commit
170b494b66
|
@ -0,0 +1,60 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using RulesEngine.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.IO;
|
||||||
|
using static RulesEngine.Extensions.ListofRuleResultTreeExtension;
|
||||||
|
|
||||||
|
namespace DemoApp
|
||||||
|
{
|
||||||
|
public class BasicDemo
|
||||||
|
{
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Running {nameof(BasicDemo)}....");
|
||||||
|
var basicInfo = "{\"name\": \"hello\",\"email\": \"abcy@xyz.com\",\"creditHistory\": \"good\",\"country\": \"canada\",\"loyalityFactor\": 3,\"totalPurchasesToDate\": 10000}";
|
||||||
|
var orderInfo = "{\"totalOrders\": 5,\"recurringItems\": 2}";
|
||||||
|
var telemetryInfo = "{\"noOfVisitsPerMonth\": 10,\"percentageOfBuyingToVisit\": 15}";
|
||||||
|
|
||||||
|
var converter = new ExpandoObjectConverter();
|
||||||
|
|
||||||
|
dynamic input1 = JsonConvert.DeserializeObject<ExpandoObject>(basicInfo, converter);
|
||||||
|
dynamic input2 = JsonConvert.DeserializeObject<ExpandoObject>(orderInfo, converter);
|
||||||
|
dynamic input3 = JsonConvert.DeserializeObject<ExpandoObject>(telemetryInfo, converter);
|
||||||
|
|
||||||
|
var inputs = new dynamic[]
|
||||||
|
{
|
||||||
|
input1,
|
||||||
|
input2,
|
||||||
|
input3
|
||||||
|
};
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "Discount.json", SearchOption.AllDirectories);
|
||||||
|
if (files == null || files.Length == 0)
|
||||||
|
throw new Exception("Rules not found.");
|
||||||
|
|
||||||
|
var fileData = File.ReadAllText(files[0]);
|
||||||
|
var workflowRules = JsonConvert.DeserializeObject<List<WorkflowRules>>(fileData);
|
||||||
|
|
||||||
|
var bre = new RulesEngine.RulesEngine(workflowRules.ToArray(), null);
|
||||||
|
|
||||||
|
string discountOffered = "No discount offered.";
|
||||||
|
|
||||||
|
List<RuleResultTree> resultList = bre.ExecuteRule("Discount", inputs);
|
||||||
|
|
||||||
|
resultList.OnSuccess((eventName) =>
|
||||||
|
{
|
||||||
|
discountOffered = $"Discount offered is {eventName} % over MRP.";
|
||||||
|
});
|
||||||
|
|
||||||
|
resultList.OnFail(() =>
|
||||||
|
{
|
||||||
|
discountOffered = "The user is not eligible for any discount.";
|
||||||
|
});
|
||||||
|
|
||||||
|
Console.WriteLine(discountOffered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,11 @@ namespace DemoApp
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class NestedInputDemo
|
public class NestedInputDemo
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public void Run()
|
||||||
{
|
{
|
||||||
|
Console.WriteLine($"Running {nameof(NestedInputDemo)}....");
|
||||||
var nestedInput = new {
|
var nestedInput = new {
|
||||||
SimpleProp = "simpleProp",
|
SimpleProp = "simpleProp",
|
||||||
NestedProp = new
|
NestedProp = new
|
||||||
|
@ -57,8 +58,7 @@ namespace DemoApp
|
||||||
}).OnFail(() =>
|
}).OnFail(() =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{workflow.WorkflowName} evaluation resulted in failure");
|
Console.WriteLine($"{workflow.WorkflowName} evaluation resulted in failure");
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,14 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
|
||||||
using RulesEngine.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Dynamic;
|
|
||||||
using System.IO;
|
|
||||||
using static RulesEngine.Extensions.ListofRuleResultTreeExtension;
|
|
||||||
|
|
||||||
namespace DemoApp
|
namespace DemoApp
|
||||||
{
|
{
|
||||||
class Program
|
static class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var basicInfo = "{\"name\": \"Dishant\",\"email\": \"dishantmunjal@live.com\",\"creditHistory\": \"good\",\"country\": \"canada\",\"loyalityFactor\": 3,\"totalPurchasesToDate\": 10000}";
|
new BasicDemo().Run();
|
||||||
var orderInfo = "{\"totalOrders\": 5,\"recurringItems\": 2}";
|
new NestedInputDemo().Run();
|
||||||
var telemetryInfo = "{\"noOfVisitsPerMonth\": 10,\"percentageOfBuyingToVisit\": 15}";
|
|
||||||
|
|
||||||
var converter = new ExpandoObjectConverter();
|
|
||||||
|
|
||||||
dynamic input1 = JsonConvert.DeserializeObject<ExpandoObject>(basicInfo, converter);
|
|
||||||
dynamic input2 = JsonConvert.DeserializeObject<ExpandoObject>(orderInfo, converter);
|
|
||||||
dynamic input3 = JsonConvert.DeserializeObject<ExpandoObject>(telemetryInfo, converter);
|
|
||||||
|
|
||||||
var inputs = new dynamic[]
|
|
||||||
{
|
|
||||||
input1,
|
|
||||||
input2,
|
|
||||||
input3
|
|
||||||
};
|
|
||||||
|
|
||||||
var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "Discount.json", SearchOption.AllDirectories);
|
|
||||||
if (files == null || files.Length == 0)
|
|
||||||
throw new Exception("Rules not found.");
|
|
||||||
|
|
||||||
var fileData = File.ReadAllText(files[0]);
|
|
||||||
var workflowRules = JsonConvert.DeserializeObject<List<WorkflowRules>>(fileData);
|
|
||||||
|
|
||||||
var bre = new RulesEngine.RulesEngine(workflowRules.ToArray(), null);
|
|
||||||
|
|
||||||
string discountOffered = "No discount offered.";
|
|
||||||
|
|
||||||
List<RuleResultTree> resultList = bre.ExecuteRule("Discount", inputs);
|
|
||||||
|
|
||||||
resultList.OnSuccess((eventName) =>
|
|
||||||
{
|
|
||||||
discountOffered = $"Discount offered is {eventName} % over MRP.";
|
|
||||||
});
|
|
||||||
|
|
||||||
resultList.OnFail(() =>
|
|
||||||
{
|
|
||||||
discountOffered = "The user is not eligible for any discount.";
|
|
||||||
});
|
|
||||||
|
|
||||||
Console.WriteLine(discountOffered);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,34 +3,23 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using RulesEngine.HelperFunctions;
|
||||||
|
|
||||||
namespace RulesEngine.Models
|
namespace RulesEngine.Models
|
||||||
{
|
{
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public class RuleParameter
|
public class RuleParameter
|
||||||
{
|
{
|
||||||
public RuleParameter(Type type)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
Name = type.Name;
|
|
||||||
}
|
|
||||||
public RuleParameter(Type type,string name)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RuleParameter(string name,object value)
|
public RuleParameter(string name,object value)
|
||||||
{
|
{
|
||||||
Type = value.GetType();
|
Value = Utils.GetTypedObject(value);
|
||||||
|
Type = Value.GetType();
|
||||||
Name = name;
|
Name = name;
|
||||||
Value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type Type { get; }
|
||||||
public Type Type { get; set; }
|
public string Name { get; }
|
||||||
public string Name { get; set; }
|
public object Value { get; }
|
||||||
public object Value { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,7 @@ namespace RulesEngine
|
||||||
for (int i = 0; i < inputs.Length; i++)
|
for (int i = 0; i < inputs.Length; i++)
|
||||||
{
|
{
|
||||||
var input = inputs[i];
|
var input = inputs[i];
|
||||||
var obj = Utils.GetTypedObject(input);
|
ruleParams.Add(new RuleParameter($"input{i + 1}", input));
|
||||||
ruleParams.Add(new RuleParameter($"input{i + 1}", obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExecuteRule(workflowName, ruleParams.ToArray());
|
return ExecuteRule(workflowName, ruleParams.ToArray());
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Version>2.0.0</Version>
|
<Version>2.0.1</Version>
|
||||||
<Copyright>Copyright (c) Microsoft Corporation.</Copyright>
|
<Copyright>Copyright (c) Microsoft Corporation.</Copyright>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<PackageProjectUrl>https://github.com/microsoft/RulesEngine</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/microsoft/RulesEngine</PackageProjectUrl>
|
||||||
|
|
|
@ -31,6 +31,24 @@ namespace RulesEngine.UnitTest
|
||||||
Assert.NotNull(typedobj.GetType().GetProperty("test"));
|
Assert.NotNull(typedobj.GetType().GetProperty("test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTypedObject_dynamicObject_multipleObjects()
|
||||||
|
{
|
||||||
|
dynamic obj = new ExpandoObject();
|
||||||
|
obj.test = "hello";
|
||||||
|
obj.testList = new List<int> { 1, 2, 3 };
|
||||||
|
dynamic obj2 = new ExpandoObject();
|
||||||
|
obj2.test = "world";
|
||||||
|
obj2.testList = new List<int> { 1, 2, 3 };
|
||||||
|
object typedobj = Utils.GetTypedObject(obj);
|
||||||
|
object typedobj2 = Utils.GetTypedObject(obj2);
|
||||||
|
Assert.IsNotType<ExpandoObject>(typedobj);
|
||||||
|
Assert.NotNull(typedobj.GetType().GetProperty("test"));
|
||||||
|
Console.WriteLine($"{typedobj.GetType()} & {typedobj2.GetType()}");
|
||||||
|
Assert.Equal(typedobj.GetType(),typedobj2.GetType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetTypedObject_nonDynamicObject()
|
public void GetTypedObject_nonDynamicObject()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue