private IFeatureFilter GetFeatureFilter(string filterName) { const string filterSuffix = "filter"; IFeatureFilter filter = _filterCache.GetOrAdd( filterName, (_) => { IEnumerable <IFeatureFilter> matchingFilters = _featureFilters.Where(f => { Type t = f.GetType(); string name = ((FilterAliasAttribute)Attribute.GetCustomAttribute(t, typeof(FilterAliasAttribute)))?.Alias; if (name == null) { name = t.Name.EndsWith(filterSuffix, StringComparison.OrdinalIgnoreCase) ? t.Name.Substring(0, t.Name.Length - filterSuffix.Length) : t.Name; } // // Feature filters can have namespaces in their alias // If a feature is configured to use a filter without a namespace such as 'MyFilter', then it can match 'MyOrg.MyProduct.MyFilter' or simply 'MyFilter' // If a feature is configured to use a filter with a namespace such as 'MyOrg.MyProduct.MyFilter' then it can only match 'MyOrg.MyProduct.MyFilter' if (filterName.Contains('.')) { // // The configured filter name is namespaced. It must be an exact match. return(string.Equals(name, filterName, StringComparison.OrdinalIgnoreCase)); } else { // // We take the simple name of a filter, E.g. 'MyFilter' for 'MyOrg.MyProduct.MyFilter' string simpleName = name.Contains('.') ? name.Split('.').Last() : name; return(string.Equals(simpleName, filterName, StringComparison.OrdinalIgnoreCase)); } }); if (matchingFilters.Count() > 1) { throw new InvalidOperationException($"Multiple feature filters match the configured filter named '{filterName}'."); } return(matchingFilters.FirstOrDefault()); } ); return(filter); }
public bool IsEnabled(string feature) { foreach (ISessionManager sessionManager in _sessionManagers) { if (sessionManager.TryGet(feature, out bool cachedEnabled)) { return(cachedEnabled); } } bool enabled = false; IFeatureSettings settings = _settingsProvider.TryGetFeatureSettings(feature); if (settings != null) { // // Check if feature is always on // If it is, result is true, goto: cache if (settings.EnabledFor.Any(featureFilter => string.Equals(featureFilter.Name, "AlwaysOn", StringComparison.OrdinalIgnoreCase))) { enabled = true; } 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 (IFeatureFilterSettings featureFilterSettings in settings.EnabledFor) { IFeatureFilter filter = GetFeatureFilter(featureFilterSettings.Name); if (filter == null) { _logger.LogWarning($"Feature filter '{featureFilterSettings.Name}' specified for feature '{feature}' was not found."); continue; } var context = new FeatureFilterEvaluationContext() { FeatureName = feature, Parameters = featureFilterSettings.Parameters }; if (filter.Evaluate(context)) { enabled = true; break; } } } } foreach (ISessionManager sessionManager in _sessionManagers) { sessionManager.Set(feature, enabled); } return(enabled); }