dynamic, , object. dynamic, .
, Func<T, bool> , Func. . , Func .
, .
public abstract class BaseBaseRuleMessage
{
public IList<int> RulesCompleted { get; set; }
public IEnumerable<Rule> FilterRules(RuleGroup ruleGroup)
{
return ruleGroup.Rules.Where(item =>
!RulesCompleted.Any(r => r.Equals(item.Id)));
}
public BaseBaseRuleMessage DeserializeToBaseBaseRuleMessage(ClientEventQueueMessage message)
{
return (BaseBaseRuleMessage) DeserializeToType(message);
}
protected abstract object DeserializeToType(ClientEventQueueMessage message);
public abstract bool ExecuteRule(Rule rule, object msg);
}
BaseRuleMessage BaseBaseRuleMessage ( .
public abstract class BaseRuleMessage<T> : BaseBaseRuleMessage
where T : BaseRuleMessage<T>
{
public abstract Func<T, bool> CompileRule(Rule r, T msg);
protected override object DeserializeToType(ClientEventQueueMessage message)
{
return JsonConvert.DeserializeObject(message.Payload, typeof(T));
}
protected BaseRuleMessage()
{
RulesCompleted = new List<int>();
}
public override bool ExecuteRule(Rule rule, object msg)
{
var message = (T) msg;
if (message == null)
{
throw new InvalidOperationException();
}
return CompileRule(rule, message).Invoke(message);
}
}
. BuildExpr, , .
public class UiTransactionUpdate : BaseRuleMessage<UiTransactionUpdate>
{
public override Func<UiTransactionUpdate, bool> CompileRule(Rule r, UiTransactionUpdate msg)
{
var expression = Expression.Parameter(typeof(UiTransactionUpdate));
Expression expr = BuildExpr(r, expression, msg);
return Expression.Lambda<Func<UiTransactionUpdate, bool>>(expr, expression).Compile();
}
public Guid TransactionId { get; set; }
public Guid GroupId { get; set; }
public decimal StatusValue { get; set; }
private Expression BuildExpr(Rule rule, ParameterExpression parameterExpression, UiTransactionUpdate message)
{
var transactionIdProperty = Expression.Property(parameterExpression, "TransactionId");
var value = Expression.Constant(rule.TransactionId);
return Expression.Equal(transactionIdProperty, value);
}
}
:
var messageTypeToTypeMap = new Dictionary<string, Func<BaseBaseRuleMessage>>
{
{"UI_UPDATE", () => new UiTransactionUpdate()}
};
var factoryFunc = messageTypeToTypeMap[message.MessageType];
message.Payload = RemoveNullGroupIdReference(jsonPayload, message.Payload);
var ruleMessage = factoryFunc.Invoke();
var deserializedMessage = ruleMessage.DeserializeToBaseBaseRuleMessage(message);
deserializedMessage.RulesCompleted = deserializedMessage.RulesCompleted ?? new List<int>();
foreach (var rule in deserializedMessage.FilterRules(ruleGroup))
{
var isTrue = deserializedMessage.ExecuteRule(rule, deserializedMessage);
}