-
Notifications
You must be signed in to change notification settings - Fork 18
Home
- Authoring Rules specifies how to create Rules for OAT.
- Delegates explores the extensibility points available in OAT via delegate declarations.
- Scripts covers usage of using Scripts directly embedded in your Rules.
Object Anaylsis Toolkit (OAT) is a meta-programming engine for processing objects using a run-time supplied Rule Set.
Rules
contain a boolean Expression
evaluated over the Clauses
inside the rule. Each Clause
performs a specified operation on the Target
object's Field
. See Authoring Rules for a detailed explanation of Rules and Clauses.
The simplest usage of OAT is to check if Rules
apply to objects.
object target;
IEnumerable<Rule> rules;
var analyzer = new Analyzer();
var rulesWhichApply = analyzer.Analyze(rules,target);
This sample from the the Walkthrough captures the weight of Overweight vehicles. It uses a two clause AND expression and a Custom OverweightOperation
delegate.
var overweightTruck = new Vehicle()
{
Weight = 30000,
Capacity = 20000,
VehicleType = VehicleType.Truck
};
var overweightCar = new Vehicle()
{
Weight = 6000,
Capacity = 5000,
VehicleType = VehicleType.Car
};
var okayTruck = new Vehicle()
{
Weight = 20000,
Capacity = 20000,
VehicleType = VehicleType.Truck
};
// Set up our Analyzer with the Custom Overweight Operation (see below)
var analyzer = new Analyzer();
analyzer.SetOperation(OverWeightOperation);
// Collect the captures from Rules which apply
var res = analyzer.GetCaptures(rules, overweightTruck);
// We get the First Rule capture and the First Clause Capture
// Since this is our OverweightOperation on an int we know we should get back a TypedClauseCapture<int>
var weight = ((TypedClauseCapture<int>)res.First().Captures[0]).Result;
// And we've captured the weight over the overweightTruck
Assert.IsTrue(weight == 30000);
// The Rule doesn't apply to our Car and Truck that isn't overweight
Assert.IsFalse(analyzer.Analyze(rules, overweightCar).Any());
Assert.IsFalse(analyzer.Analyze(rules, okayTruck).Any());
class Vehicle
{
public int Weight;
public int Capacity { get; set; }
public VehicleType VehicleType { get; internal set; }
}
enum VehicleType
{
Motorcycle,
Car,
Truck
}
var overweightRule = new VehicleRule("Overweight Truck")
{
// Both clauses must be true for this Rule to apply
Expression = "Overweight AND IsTruck",
Target = "Vehicle",
Clauses = new List<Clause>()
{
new Clause(Operation.Custom)
{
Label = "Overweight",
CustomOperation = "OVERWEIGHT",
Capture = true
},
new Clause(Operation.Equals)
{
Label = "IsTruck",
Data = new List<string>() { "Truck" }
}
}
}
OatOperation OverweightOperation = new OatOperation(Operation.Custom, analyzer)
{
CustomOperation = "OVERWEIGHT",
OperationDelegate = OverweightOperationDelegate,
ValidationDelegate = OverweightOperationValidationDelegate
};
public OperationResult OverweightOperationDelegate(Clause clause, object? state1, object? state2, IEnumerable<ClauseCapture>? captures)
{
if (state1 is Vehicle vehicle)
{
var res = vehicle.Weight > vehicle.Capacity;
if ((res && !clause.Invert) || (clause.Invert && !res))
{
// The rule applies and is true and the capture is available if capture is enabled
return new OperationResult(true, clause.Capture ? new TypedClauseCapture<int>(clause, vehicle.Weight, state1, state2) : null);
}
}
return new OperationResult(false, null);
}
public IEnumerable<Violation> OverweightOperationValidationDelegate(Rule r, Clause c)
{
var violations = new List<Violation>();
if (r.Target != "Vehicle")
{
violations.Add(new Violation("Overweight operation requires a Vehicle object", r, c));
}
if (c.Data != null || c.DictData != null)
{
violations.Add(new Violation("Overweight operation takes no data.", r, c));
}
return violations;
}
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.