/// <summary> /// Evaluates a feature flag for a given user. /// </summary> /// <param name="flag">the flag; must not be null</param> /// <param name="user">the user</param> /// <param name="eventFactory">an <see cref="EventFactory"/> instance that will be called to produce any necessary /// prerequisite flag events</param> /// <returns>an <see cref="EvalResult"/> containing the evaluation result as well as any events that were produced; /// the PrerequisiteEvents list will always be non-null</returns> public EvalResult Evaluate(FeatureFlag flag, User user, EventFactory eventFactory) { if (flag.Key == FlagKeyToTriggerErrorForTesting) { throw new Exception(ErrorMessageForTesting); } if (user == null || user.Key == null) { _logger.Warn("User or user key is null when evaluating flag: {0} returning null", flag.Key); return(new EvalResult( new EvaluationDetail <LdValue>(LdValue.Null, null, EvaluationReason.ErrorReason(EvaluationErrorKind.UserNotSpecified)), ImmutableList.Create <EvaluationEvent>())); } var scope = new EvalScope(this, flag, user, eventFactory); return(scope.Evaluate()); }
// Checks prerequisites if any; returns null if successful, or an EvaluationReason if we have to // short-circuit due to a prerequisite failure. May add events to _prereqEvents. private EvaluationReason?CheckPrerequisites() { foreach (var prereq in _flag.Prerequisites) { var prereqOk = true; var prereqFeatureFlag = _parent._featureFlagGetter(prereq.Key); if (prereqFeatureFlag == null) { _parent._logger.Error("Could not retrieve prerequisite flag \"{0}\" when evaluating \"{1}\"", prereq.Key, _flag.Key); prereqOk = false; } else { var prereqScope = new EvalScope(_parent, prereqFeatureFlag, _user, _eventFactory); var prereqEvalResult = prereqScope.Evaluate(); var prereqDetails = prereqEvalResult.Result; // Note that if the prerequisite flag is off, we don't consider it a match no matter // what its off variation was. But we still need to evaluate it in order to generate // an event. if (!prereqFeatureFlag.On || prereqDetails.VariationIndex == null || prereqDetails.VariationIndex.Value != prereq.Variation) { prereqOk = false; } foreach (var subPrereqEvent in prereqEvalResult.PrerequisiteEvents) { _prereqEvents.Add(subPrereqEvent); } _prereqEvents.Add(_eventFactory.NewPrerequisiteEvaluationEvent(prereqFeatureFlag, _user, prereqDetails, _flag)); } if (!prereqOk) { return(EvaluationReason.PrerequisiteFailedReason(prereq.Key)); } } return(null); }