Renaming from filter to expression and adding a public interface.

pull/3/head
Sean McArde 2023-07-11 14:50:58 -07:00
parent 1685a3e290
commit 65a7db7250
7 changed files with 52 additions and 35 deletions

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace McRule {
public interface IExpressionRule {
string TargetType { get; set; }
Expression<Func<T, bool>>? GetExpression<T>();
}
}

View File

@ -4,11 +4,11 @@ using System.Text;
namespace McRule {
public class FilterPolicy : FilterRuleCollection {
public class ExpressionPolicy : ExpressionRuleCollection {
public Guid Id { get; set; }
public string Name { get; set; }
public string[] Properties { get; set; }
public FilterPolicy() : base() { }
public ExpressionPolicy() : base() { }
}
}

View File

@ -5,17 +5,24 @@ using System.Text;
namespace McRule {
public class FilterRuleCollection {
public class ExpressionRuleCollection : IExpressionRule {
public Guid Id { get; set; } = Guid.NewGuid();
public FilterRuleCollection Rule { get; set; }
public PredicateExpressionPolicyExtensions.RuleOperator RuleOperator { get; set; } = PredicateExpressionPolicyExtensions.RuleOperator.And;
public IEnumerable<IExpressionRule> Rules { get; set; }
public string TargetType { get; set; }
public IEnumerable<FilterRule> Rules { get; set; }
public FilterRuleCollection() { }
public ExpressionRuleCollection() { }
public Expression<Func<T, bool>>? GetExpression<T>() {
var expressions = Rules.Select(x => x.GetExpression<T>());
return (RuleOperator == PredicateExpressionPolicyExtensions.RuleOperator.Or)
? PredicateExpressionPolicyExtensions.CombineOr<T>(expressions)
: PredicateExpressionPolicyExtensions.CombineAnd<T>(expressions);
}
}
public class FilterRule {
public class ExpressionRule : IExpressionRule {
public string TargetType { get; set; }
public string Property { get; set; }
public string Value { get; set; }
@ -24,15 +31,15 @@ namespace McRule {
internal (string, string, string) Rule => (TargetType, Property, Value);
public FilterRule() { }
public ExpressionRule() { }
public FilterRule(string TargetType, string Property, string Value) {
public ExpressionRule(string TargetType, string Property, string Value) {
this.TargetType = TargetType;
this.Property = Property;
this.Value = Value;
}
public FilterRule((string, string, string) input) {
public ExpressionRule((string, string, string) input) {
TargetType = input.Item1;
Property = input.Item2;
Value = input.Item3;
@ -41,7 +48,7 @@ namespace McRule {
/// <summary>
/// Returns an expression tree targeting an object type based on policy parameters.
/// </summary>
public Expression<Func<T, bool>>? GetFilterExpression<T>() {
public Expression<Func<T, bool>>? GetExpression<T>() {
if (!(typeof(T).Name.Equals(this.TargetType, StringComparison.CurrentCultureIgnoreCase))) return null;
if (cachedExpression == null) {
@ -56,7 +63,7 @@ namespace McRule {
}
public string GetFilterString<T>() {
return this.GetFilterExpression<T>()?.ToString() ?? String.Empty;
return this.GetExpression<T>()?.ToString() ?? String.Empty;
}
}
}

View File

@ -12,8 +12,8 @@ public static class PredicateExpressionPolicyExtensions {
Or
}
public static FilterRule ToFilterRule(this (string, string, string) tuple) {
return new FilterRule(tuple);
public static ExpressionRule ToFilterRule(this (string, string, string) tuple) {
return new ExpressionRule(tuple);
}
/// <summary>
@ -259,7 +259,7 @@ public static class PredicateExpressionPolicyExtensions {
/// <summary>
/// Generate an expression tree targeting an object type based on a given policy.
/// </summary>
public static Expression<Func<T, bool>>? GetPredicateExpression<T>(this FilterRuleCollection policy) {
public static Expression<Func<T, bool>>? GetPredicateExpression<T>(this ExpressionRuleCollection policy) {
Expression<Func<T, bool>> truePredicate = x => true;
Expression<Func<T, bool>> falsePredicate = x => false;
@ -270,18 +270,17 @@ public static class PredicateExpressionPolicyExtensions {
if (!(typeof(T).Name.Equals(rule.TargetType, StringComparison.CurrentCultureIgnoreCase))) {
continue;
}
var expression = rule.GetFilterExpression<T>();
var expression = rule.GetExpression<T>();
if (expression != null) predicates.Add(expression);
}
var first = policy.Rule?.GetPredicateExpression<T>();
var second = CombinePredicates<T>(predicates, policy.RuleOperator);
var expressions = CombinePredicates<T>(predicates, policy.RuleOperator);
if (first == null && second == null) {
if (expressions == null) {
System.Diagnostics.Debug.WriteLine($"No predicates available for type: <{typeof(T).Name}> in policy: {policy.Id}");
return falsePredicate;
} else if (first != null && second == null) return first;
else if (first == null && second != null) return second;
else return CombinePredicates<T>(first, second, policy.RuleOperator);
}
return expressions;
}
}

View File

@ -6,6 +6,6 @@ namespace McRule {
public interface PolicyMap {
string Name { get; }
string Description { get; }
Func<FilterPolicy,bool> IsMatch(FilterPolicy policy);
Func<ExpressionPolicy,bool> IsMatch(ExpressionPolicy policy);
}
}

View File

@ -122,14 +122,14 @@ public static class FilterRuleManager
public class FilterRuleRepository
{
private Dictionary<string, FilterRuleCollection> roleRuleMap { get; } =
new Dictionary<string, FilterRuleCollection>();
private Dictionary<string, ExpressionRuleCollection> roleRuleMap { get; } =
new Dictionary<string, ExpressionRuleCollection>();
public void AddRule(string role, FilterRuleCollection rule) => roleRuleMap.Add(role, rule);
public void AddRule(string role, ExpressionRuleCollection rule) => roleRuleMap.Add(role, rule);
public FilterRuleCollection? GetRule(string role)
public ExpressionRuleCollection? GetRule(string role)
{
FilterRuleCollection result = null;
ExpressionRuleCollection result = null;
roleRuleMap.TryGetValue(role, out result);
return result;
}

View File

@ -20,11 +20,11 @@ var users = new List<User> {
//users.Dump();
var filterPolicy = new FilterPolicy
var filterPolicy = new ExpressionPolicy
{
Name = "DHS or OHA",
Properties = new string[] { }, // Can't do anything with this yet
Rules = new List<FilterRule>()
Rules = new List<ExpressionRule>()
{
("User", "tags", "IT").ToFilterRule(),
("User", "agency", "ODHSOHA").ToFilterRule(),
@ -39,11 +39,11 @@ users.Where(filterExpression).Dump($"{filterPolicy.Name} operator {filterPolicy.
filterPolicy = new FilterPolicy
filterPolicy = new ExpressionPolicy
{
Name = "All DAS *ians case sensitive",
Properties = new string[] { }, // Can't do anything with this yet
Rules = new List<FilterRule>
Rules = new List<ExpressionRule>
{
("User", "first", "*ian").ToFilterRule(),
("User", "agency", "DAS").ToFilterRule()
@ -53,11 +53,11 @@ filterExpression = filterPolicy.GetPredicateExpression<User>();
filterPolicy.Dump(filterPolicy.Name);
users.Where(filterExpression).Dump($"operator {filterPolicy.RuleOperator}");
filterPolicy = new FilterPolicy
filterPolicy = new ExpressionPolicy
{
Name = "All DAS *ians case insensitive",
Properties = new string[] { }, // Can't do anything with this yet
Rules = new List<FilterRule>
Rules = new List<ExpressionRule>
{
("User", "first", "~*ian").ToFilterRule(),
("User", "agency", "DAS").ToFilterRule()