/// <summary> /// Creates the method which runs the condition evalulate method. /// </summary> /// <param name="sb">The class writer.</param> /// <param name="info">The property info.</param> /// <param name="additionParameterMethods">The list of additional parameter methods.</param> /// <param name="classAddParams">True if the class has additional parameters method.</param> private static void EvalDictionaryConditionMethod( ClassWriter sb, PropertyInfo info, IReadOnlyCollection <string> additionParameterMethods, bool classAddParams) { string?matchingAdditionalParamtersMethod = additionParameterMethods.FirstOrDefault(x => x.Equals($"{ClassInfo.AdditionalParamtersMethodPrefix}{info.Name}", StringComparison.Ordinal)); List <ParamDef> allParameters = new List <ParamDef>() { new ParamDef("string", "key", "The key, in the condition dictionary, to evaluate."), new ParamDef("Random", "rdm", "The random number generator"), }; allParameters.AddRange(info.Variables.Select(v => new ParamDef($"LegendsGenerator.Contracts.Things.BaseThing", v.Name, "One of the variables which will be passed to the compiled condition.")).ToList()); if (matchingAdditionalParamtersMethod != null || classAddParams) { allParameters.Add(new ParamDef( "IDictionary<string, LegendsGenerator.Contracts.Things.BaseThing>", "additionalParameters", $"Additional parameters as defined by AdditionalParametersForClass and AdditionalParametersFor{info.Name} methods, or the upstream additional parameters.")); } using var braces = sb.AddMethod( new MethodDefinition($"Eval{info.Name}") { SummaryDoc = $"Evaluates the expressions in the {info.Name} property with the given parameters.", ReturnsDoc = "The result of evaluation.", Access = info.Protected ? AccessLevel.Protected : AccessLevel.Public, Type = info.ReturnType, Parameters = allParameters, }); sb.AppendLine($"if (this.Compiler == null || this.compiledCondition{info.Name} == null)"); sb.StartBrace(); sb.AppendLine("throw new InvalidOperationException(\"Definition must be attached before any Eval method is called.\");"); sb.EndBrace(); sb.AppendLine(); sb.AddDictionary( "Dictionary<string, LegendsGenerator.Contracts.Things.BaseThing>", "param", info.Variables.Select(x => x.Name).ToDictionary(x => x, x => x)); if (matchingAdditionalParamtersMethod != null || classAddParams) { sb.AppendLine("foreach(var additionalParameter in additionalParameters)"); sb.StartBrace(); sb.AppendLine("param[additionalParameter.Key] = additionalParameter.Value;"); sb.EndBrace(); sb.AppendLine(); } sb.AppendLine("try"); sb.StartBrace(); sb.AppendLine($"return this.compiledCondition{info.Name}[key].Value.Evaluate(rdm, param);"); sb.EndBrace(); sb.AppendLine("catch (Exception ex)"); sb.StartBrace(); sb.AppendLine($"throw this.GetConditionException($\"{info.Name}{{key}}\", ex);"); sb.EndBrace(); }