/// <summary> /// Evaluate /// </summary> public override object Evaluate(Act act, CdssContext <Patient> context, IDictionary <String, Object> scopes) { var value = act.GetType().GetRuntimeProperty(this.PropertyName) as IList; value?.Add(this.Element); return(value); }
/// <summary> /// Evaluate the "when" clause /// </summary> public bool Evaluate <TData>(CdssContext <TData> context) { if (this.m_compiledExpression == null) { this.Compile <TData>(context); } lock (m_lockObject) { st_contextReference = context; return(this.m_compiledExpression.Invoke(context)); } }
/// <summary> /// Evaluate the actions /// </summary> /// <returns></returns> public IEnumerable <Act> Evaluate(CdssContext <Patient> context) { List <Act> retVal = new List <Act>(); Dictionary <String, Object> calculatedScopes = new Dictionary <string, object>() { { ".", context.Target } }; foreach (var itm in this.Action) { Act act = null; if (itm.Element is String) // JSON { itm.Element = s_serializer.DeSerialize <Act>(itm.Element as String); // Load all concepts for the specified objects } act = (itm.Element as Act).Clone() as Act; act.Participations = new List <ActParticipation>((itm.Element as Act).Participations.Select(o => o.Clone() as ActParticipation)); act.Relationships = new List <ActRelationship>((itm.Element as Act).Relationships.Select(o => o.Clone() as ActRelationship)); act.Protocols = new List <ActProtocol>();// (itm.Element as Act).Protocols); // Now do the actions to the properties as stated foreach (var instr in itm.Do) { instr.Evaluate(act, context, calculatedScopes); } // Assign this patient as the record target act.Key = act.Key ?? Guid.NewGuid(); Guid pkey = Guid.NewGuid(); act.Participations.Add(new ActParticipation(ActParticipationKey.RecordTarget, context.Target.Key) { ParticipationRole = new Core.Model.DataTypes.Concept() { Key = ActParticipationKey.RecordTarget, Mnemonic = "RecordTarget" }, Key = pkey }); // Add record target to the source for forward rules context.Target.Participations.Add(new ActParticipation(ActParticipationKey.RecordTarget, context.Target) { SourceEntity = act, ParticipationRole = new Core.Model.DataTypes.Concept() { Key = ActParticipationKey.RecordTarget, Mnemonic = "RecordTarget" }, Key = pkey }); act.CreationTime = DateTimeOffset.Now; // The act to the return value retVal.Add(act); } return(retVal); }
/// <summary> /// Evaluate the specified action on the object /// </summary> public override object Evaluate(Act act, CdssContext <Patient> context, IDictionary <String, Object> scopes) { var propertyInfo = act.GetType().GetRuntimeProperty(this.PropertyName); if (this.Element != null) { propertyInfo.SetValue(act, this.Element); } else { var setValue = this.GetValue(act, context, scopes); //exp.TypeRegistry.RegisterSymbol("data", expressionParm); if (Core.Model.Map.MapUtil.TryConvert(setValue, propertyInfo.PropertyType, out setValue)) { propertyInfo.SetValue(act, setValue); } } return(propertyInfo.GetValue(act)); }
/// <summary> /// Get the specified value /// </summary> public object GetValue(Act act, CdssContext <Patient> context, IDictionary <String, Object> scopes) { if (this.m_setter == null) { Func <String, Object> varFetch = (a) => context.Get(a); var interpretor = new Interpreter(InterpreterOptions.Default) .Reference(typeof(TimeSpan)) .Reference(typeof(Guid)) .Reference(typeof(DateTimeOffset)) .Reference(typeof(Types)); // Scope if (!String.IsNullOrEmpty(this.ScopeSelector) && this.m_setter == null) { var scopeProperty = context.Target.GetType().GetRuntimeProperty(this.ScopeSelector); if (scopeProperty == null) { return(null); // no scope } // Where clause? if (!String.IsNullOrEmpty(this.WhereFilter) && this.m_scopeSelectMethod == null) { var itemType = scopeProperty.PropertyType.GenericTypeArguments[0]; var predicateType = typeof(Func <,>).MakeGenericType(new Type[] { itemType, typeof(bool) }); var builderMethod = typeof(QueryExpressionParser).GetGenericMethod(nameof(QueryExpressionParser.BuildLinqExpression), new Type[] { itemType }, new Type[] { typeof(NameValueCollection) }); this.m_linqExpression = builderMethod.Invoke(null, new Object[] { NameValueCollection.ParseQueryString(this.WhereFilter) }) as Expression; this.m_compiledExpression = (this.m_linqExpression as LambdaExpression).Compile(); // Call where clause builderMethod = typeof(Expression).GetGenericMethod(nameof(Expression.Lambda), new Type[] { predicateType }, new Type[] { typeof(Expression), typeof(ParameterExpression[]) }); var firstMethod = typeof(Enumerable).GetGenericMethod("FirstOrDefault", new Type[] { itemType }, new Type[] { scopeProperty.PropertyType, predicateType }); this.m_scopeSelectMethod = (MethodInfo)firstMethod; } interpretor = interpretor.Reference(this.m_scopeSelectMethod.ReturnType); this.m_setter = interpretor.Parse(this.ValueExpression, new Parameter("_", this.m_scopeSelectMethod.ReturnType)); } else { this.m_setter = interpretor.Parse(this.ValueExpression, new Parameter("_", typeof(CdssContext <Patient>))); } } Object setValue = null; // Where clause? if (!String.IsNullOrEmpty(this.ScopeSelector)) { // Is the scope selector key present? String scopeKey = $"{this.ScopeSelector}.{this.WhereFilter}"; object scope = null; if (!scopes.TryGetValue(scopeKey, out scope)) { var scopeProperty = context.Target.GetType().GetRuntimeProperty(this.ScopeSelector); var scopeValue = scopeProperty.GetValue(context.Target); scope = scopeValue; if (!String.IsNullOrEmpty(this.WhereFilter)) { scope = this.m_scopeSelectMethod.Invoke(null, new Object[] { scopeValue, this.m_compiledExpression }); } lock (scopes) if (!scopes.ContainsKey(scopeKey)) { scopes.Add(scopeKey, scope); } } setValue = this.m_setter.Invoke(scope); } else { setValue = this.m_setter.Invoke(context); } return(setValue); }
/// <summary> /// Evaluate the expression /// </summary> /// <returns></returns> public abstract object Evaluate(Act act, CdssContext <Patient> context, IDictionary <String, Object> scopes);
/// <summary> /// Compile the expression /// </summary> public Expression Compile <TData>(CdssContext <TData> context) { ParameterExpression expressionParm = Expression.Parameter(typeof(CdssContext <TData>), "_scope"); Expression body = null; // Iterate and perform binary operations foreach (var itm in this.Clause) { Expression clauseExpr = null; if (itm is ProtocolWhenClauseCollection) { clauseExpr = Expression.Invoke((itm as ProtocolWhenClauseCollection).Compile <TData>(context), expressionParm); } else if (itm is WhenClauseHdsiExpression) { var varDict = new Dictionary <String, Func <Object> >(); foreach (var varRef in context.Variables) { varDict.Add(varRef, () => st_contextReference?.Get(varRef)); } var hdsiExpr = itm as WhenClauseHdsiExpression; clauseExpr = QueryExpressionParser.BuildLinqExpression <TData>(NameValueCollection.ParseQueryString(hdsiExpr.Expression), "s", varDict, safeNullable: true, forceLoad: true, lazyExpandVariables: true); clauseExpr = Expression.Invoke(clauseExpr, Expression.MakeMemberAccess(expressionParm, typeof(CdssContext <TData>).GetProperty("Target"))); if (hdsiExpr.NegationIndicator) { clauseExpr = Expression.Not(clauseExpr); } this.m_tracer.TraceVerbose("Converted WHEN {0} > {1}", hdsiExpr.Expression, clauseExpr); } else if (itm is XmlLambdaExpression) { var xmlLambda = itm as XmlLambdaExpression; (itm as XmlLambdaExpression).InitializeContext(null); // replace parameter clauseExpr = Expression.Invoke(((itm as XmlLambdaExpression).ToExpression() as LambdaExpression), expressionParm); } else { var interpreter = new Interpreter(InterpreterOptions.Default) .Reference(typeof(TData)) .Reference(typeof(Guid)) .Reference(typeof(TimeSpan)) .Reference(typeof(Types)) .EnableReflection(); var linqAction = interpreter.ParseAsExpression <Func <CdssContext <TData>, bool> >(itm.ToString(), "_"); clauseExpr = Expression.Invoke(linqAction, expressionParm); //clauseExpr = Expression.Invoke(d, expressionParm); } // Append to master expression if (body == null) { body = clauseExpr; } else { body = Expression.MakeBinary((ExpressionType)Enum.Parse(typeof(ExpressionType), this.Operator.ToString()), body, clauseExpr); } } // Wrap and compile var objParm = Expression.Parameter(typeof(Object)); var bodyCondition = Expression.Lambda <Func <CdssContext <TData>, bool> >(body, expressionParm); var invoke = Expression.Invoke( bodyCondition, Expression.Convert(objParm, typeof(CdssContext <TData>)) ); var uncompiledExpression = Expression.Lambda <Func <Object, bool> >(invoke, objParm); this.DebugView = uncompiledExpression.ToString(); this.m_compiledExpression = uncompiledExpression.Compile(); return(uncompiledExpression); }