Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }