/// <summary> /// This rule check if the source entity has any list properties that contain types that has rules set against the target entity. /// ie. a Job with a sub job line that has restrictions on the target. /// </summary> /// <param name="entityRules">This can be a list of all the rules or an already filtered list, the rules will be checked again.</param> /// <param name="sourceEntity">The entity that acts as the source for the rule</param> /// <param name="targetEntity">The entity that acts as the target for the rule.</param> /// <param name="ruleApplicator">The event or process the event is applied to.</param> /// <returns></returns> public IJarsRule EvaluateSourceChildListsAgainstTarget(List <IJarsRule> entityRules, IEntityBase sourceEntity, IEntityBase targetEntity, RuleRunsOn ruleApplicator) { var sourceDictionaryListTypes = sourceEntity.GetGenericListTypesDictionary(); //get the list of possible rules where the target type is the type of the key value. //https://dotnetable.wordpress.com/2015/06/20/find-all-items-in-list-which-exist-in-another-list-using-linq/ //this can be seen as retrieve all the values from entityRules which also exist in dictionary values. var filteredRules = (from er in entityRules join kVals in sourceDictionaryListTypes.Values on er.SourceTypeName equals kVals.Name select er).Where(r => r.RuleRunsOn.Contains(ruleApplicator.ToString())).ToList(); if (!filteredRules.Any()) { return(null); } /* * * var listType = typeof(List<>); * var constructedListType = listType.MakeGenericType(t); * var instance = Activator.CreateInstance(constructedListType); * */ IJarsRule failRule = null; //test each collection foreach (var dictionaryKey in sourceDictionaryListTypes) { //var itemsListType = typeof(IList<>); //var defaultList = itemsListType.MakeGenericType(dictionaryKey.Value); var sourceItems = (IList)sourceEntity.GetType() .GetProperty(dictionaryKey.Key) .GetValue(sourceEntity); //test the property type first foreach (var subItem in sourceItems) { //test broad failRule = EvaluateSourceAgainstTargetType(filteredRules, subItem as IEntityBase, targetEntity, ruleApplicator); if (failRule != null) { return(failRule); } //test narrow failRule = EvaluateSourceAgainstTarget(filteredRules, subItem as IEntityBase, targetEntity, ruleApplicator); if (failRule != null) { return(failRule); } } } return(null); }