private ContextualFeatureFilterEvaluator GetContextualFeatureFilter(string filterName, Type appContextType) { if (appContextType == null) { throw new ArgumentNullException(nameof(appContextType)); } ContextualFeatureFilterEvaluator filter = _contextualFeatureFilterCache.GetOrAdd( $"{filterName}{Environment.NewLine}{appContextType.FullName}", _ => { IFeatureFilterMetadata metadata = GetFeatureFilterMetadata(filterName); return(ContextualFeatureFilterEvaluator.IsContextualFilter(metadata, appContextType) ? new ContextualFeatureFilterEvaluator(metadata, appContextType) : null); } ); return(filter); }
private async Task <bool> IsEnabledAsync <TContext>(string feature, TContext appContext, bool useAppContext) { foreach (ISessionManager sessionManager in _sessionManagers) { bool?readSessionResult = await sessionManager.GetAsync(feature).ConfigureAwait(false); if (readSessionResult.HasValue) { return(readSessionResult.Value); } } bool enabled = false; FeatureDefinition featureDefinition = await _featureDefinitionProvider.GetFeatureDefinitionAsync(feature).ConfigureAwait(false); if (featureDefinition != null) { // Check if feature is always on // If it is, result is true, goto: cache if (featureDefinition.EnabledFor.Any(featureFilter => string.Equals(featureFilter.Name, "AlwaysOn", StringComparison.OrdinalIgnoreCase))) { enabled = true; } else if (featureDefinition.EnabledFor.Any(featureFilter => string.Equals(featureFilter.Name, "AlwaysOff", StringComparison.OrdinalIgnoreCase))) { return(false); } else { // For all enabling filters listed in the feature's state calculate if they return true // If any executed filters return true, return true foreach (FeatureFilterConfiguration featureFilterConfiguration in featureDefinition.EnabledFor) { IFeatureFilterMetadata filter = GetFeatureFilterMetadata(featureFilterConfiguration.Name); if (filter == null) { string errorMessage = $"The feature filter '{featureFilterConfiguration.Name}' specified for feature '{feature}' was not found."; if (!_options.IgnoreMissingFeatureFilters) { throw new FeatureManagementException(FeatureManagementError.MissingFeatureFilter, errorMessage); } _logger.LogWarning(errorMessage); continue; } var context = new FeatureFilterEvaluationContext { FeatureName = feature, Parameters = featureFilterConfiguration.Parameters }; // IContextualFeatureFilter if (useAppContext) { ContextualFeatureFilterEvaluator contextualFilter = GetContextualFeatureFilter(featureFilterConfiguration.Name, typeof(TContext)); if (contextualFilter != null && await contextualFilter.EvaluateAsync(context, appContext) .ConfigureAwait(false)) { enabled = true; break; } } // IFeatureFilter if (filter is IFeatureFilter featureFilter && await featureFilter.EvaluateAsync(context).ConfigureAwait(false)) { enabled = true; break; } } } } foreach (ISessionManager sessionManager in _sessionManagers) { await sessionManager.SetAsync(feature, enabled).ConfigureAwait(false); } return(enabled); }