/// <summary> /// Inserts the specified object /// </summary> public object Insert(object value) { try { var data = JavascriptUtils.ToModel(value); if (data == null) { throw new ArgumentException("Could not parse value for insert"); } var cacheKey = $"{data.Type}.{data.Key}"; this.m_adhocCache?.Remove(cacheKey); var idp = typeof(IRepositoryService <>).MakeGenericType(data.GetType()); var idpInstance = ApplicationServiceContext.Current.GetService(idp) as IRepositoryService; if (idpInstance == null) { throw new KeyNotFoundException($"The repository service for {data.GetType()} was not found. Ensure an IRepositoryService<{data.GetType()}> is registered"); } return(JavascriptUtils.ToViewModel(idpInstance.Insert(data))); } catch (TargetInvocationException e) { this.m_tracer.TraceError("Persistence inserting in BRE: {0} - {1}", value, e.InnerException); throw new Exception($"Persistence inserting in BRE : {value}", e.InnerException); } catch (Exception e) { this.m_tracer.TraceError("Error inserting in BRE: {0} - {1}", value, e); throw new Exception($"Error inserting in BRE: {value}", e); } }
/// <summary> /// Gets the specified data from the underlying data-store /// </summary> public object Get(String type, String id) { try { var guidId = Guid.Parse(id); var cacheKey = $"{type}.{id}"; // First, does the object existing the cache ExpandoObject retVal = this.m_adhocCache?.Get <ExpandoObject>(cacheKey); if (retVal == null) { Type dataType = this.m_binder.BindToType(null, type); if (dataType == null) { throw new InvalidOperationException($"Cannot find type information for {type}"); } var idp = typeof(IRepositoryService <>).MakeGenericType(dataType); var idpInstance = ApplicationServiceContext.Current.GetService(idp) as IRepositoryService; if (idpInstance == null) { throw new KeyNotFoundException($"The repository service for {type} was not found. Ensure an IRepositoryService<{type}> is registered"); } retVal = JavascriptUtils.ToViewModel(idpInstance.Get(guidId)); this.m_adhocCache?.Add(cacheKey, retVal, new TimeSpan(0, 0, 30)); } return(retVal); } catch (Exception e) { this.m_tracer.TraceError("Error getting BRE object: {0}/{1} - {2}", type, id, e); throw new Exception($"Error getting BRE object: {type}/{id}", e); } }
/// <summary> /// Executes the business rule /// </summary> public object ExecuteRule(String action, Object data) { var sData = JavascriptUtils.ToModel(data); var retVal = this.m_owner.Invoke(action, sData); return(JavascriptUtils.ToViewModel(retVal)); }
/// <summary> /// Perform actual invokation on all objects /// </summary> public TBinding Invoke <TBinding>(string triggerName, TBinding data) where TBinding : IdentifiedData { lock (this.m_lock) { using (AuthenticationContext.EnterSystemContext()) { if (data == default(TBinding)) { return(data); } var callList = this.GetCallList(data.GetType(), triggerName); callList = callList.Union(this.GetCallList <TBinding>(triggerName), this.m_javascriptComparer).ToList(); var retVal = data; if (callList.Count() > 0) { dynamic viewModel = JavascriptUtils.ToViewModel(retVal); foreach (var c in callList) { try { // There is a guard so let's execute it if (c.Guard == null || QueryExpressionParser.BuildLinqExpression <TBinding>(c.Guard).Compile()(data)) { viewModel = c.Callback.DynamicInvoke(viewModel); } } catch (JavaScriptException e) { this.m_tracer.TraceError("JS ERROR: Error running {0} for {1} @ {2}:{3} \r\n Javascript Stack: {4} \r\n C# Stack: {5}", triggerName, data, e.Location.Source, e.LineNumber, e.CallStack, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", e); } catch (TargetInvocationException e) when(e.InnerException is JavaScriptException je) { this.m_tracer.TraceError("JS ERROR: Error running {0} for {1} @ {2}:{3} \r\n Javascript Stack: {4} \r\n C# Stack: {5}", triggerName, data, je.Location.Source, je.LineNumber, je.CallStack, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", je); } catch (Exception e) { this.m_tracer.TraceError("Error running {0} for {1} : {2}", triggerName, data, e); throw new JsBusinessRuleException($"Error running business rule {c.Id} - {triggerName} for {data}", e); } } retVal = (TBinding)JavascriptUtils.ToModel(viewModel).CopyAnnotations(retVal); } return(retVal); } } }
/// <summary> /// Validate the data object if validation is available /// </summary> public List <DetectedIssue> Validate <TBinding>(TBinding data) where TBinding : IdentifiedData { lock (this.m_lock) { using (AuthenticationContext.EnterSystemContext()) { var callList = this.GetCallList(data.GetType(), "Validate").Union(this.GetCallList <TBinding>("Validate"), this.m_javascriptComparer).Distinct(); var retVal = new List <DetectedIssue>(); var vmData = JavascriptUtils.ToViewModel(data); foreach (var c in callList) { try { object[] issues = null; issues = c.Callback.DynamicInvoke(vmData) as object[]; retVal.AddRange(issues.Cast <IDictionary <String, Object> >().Select(o => new DetectedIssue() { Text = o.ContainsKey("text") ? o["text"]?.ToString() : null, Priority = o.ContainsKey("priority") ? (DetectedIssuePriorityType)(int)(double)o["priority"] : DetectedIssuePriorityType.Information, TypeKey = o.ContainsKey("type") ? Guid.Parse(o["type"].ToString()) : DetectedIssueKeys.BusinessRuleViolationIssue })); } catch (JavaScriptException e) { this.m_tracer.TraceError("Error validating {0} (rule: {1}) : {2}", data, c.Id, e); return(new List <DetectedIssue>() { new DetectedIssue() { Priority = DetectedIssuePriorityType.Error, Text = $"Error validating {data} (rule: {c.Id}) - {e.Message} @ {e.LineNumber}" } }); } catch (Exception e) { this.m_tracer.TraceError("Error validating {0} (rule: {1}) : {2}", data, c.Id, e); return(new List <DetectedIssue>() { new DetectedIssue() { Priority = DetectedIssuePriorityType.Error, Text = $"Error validating {data} (rule: {c.Id}) - {e.Message}" } }); } } return(retVal); } } }
/// <summary> /// Gets the specified data from the underlying data-store /// </summary> public object Obsolete(String type, Guid id) { try { Type dataType = this.m_binder.BindToType(null, type); var idp = typeof(IRepositoryService <>).MakeGenericType(dataType); var idpInstance = ApplicationServiceContext.Current.GetService(idp) as IRepositoryService; if (idpInstance == null) { throw new KeyNotFoundException($"The repository service for {type} was not found. Ensure an IRepositoryService<{type}> is registered"); } return(JavascriptUtils.ToViewModel(idpInstance.Obsolete(id))); } catch (Exception e) { this.m_tracer.TraceError("Error obsoleting BRE object: {0}/{1} - {2}", type, id, e); throw new Exception($"Error obsoleting BRE object: {type}/{id}", e); } }
/// <summary> /// Finds the specified data /// </summary> public object Find(String type, String query) { try { Type dataType = this.m_binder.BindToType(null, type); if (dataType == null) { throw new InvalidOperationException($"Cannot find type information for {type}"); } var idp = typeof(IRepositoryService <>).MakeGenericType(dataType); var idpInstance = ApplicationServiceContext.Current.GetService(idp) as IRepositoryService; if (idpInstance == null) { throw new KeyNotFoundException($"The repository service for {type} was not found. Ensure an IRepositoryService<{type}> is registered"); } var expr = QueryExpressionParser.BuildLinqExpression(dataType, NameValueCollection.ParseQueryString(query)); var results = idpInstance.Find(expr).OfType <IdentifiedData>(); return(JavascriptUtils.ToViewModel(new Bundle() { Item = results.ToList(), TotalResults = results.Count() })); } catch (TargetInvocationException e) { this.m_tracer.TraceError("Persistence searching from BRE: {0}?{1} - {2}", type, query, e.InnerException); throw new Exception($"Persistence searching from BRE : {type}?{query}", e.InnerException); } catch (Exception e) { this.m_tracer.TraceError("Error searching from BRE: {0}?{1} - {2}", type, query, e); throw new Exception($"Error searching from BRE: {type}?{query}", e); } }