示例#1
0
        internal EvalResult Evaluate(User user, IFeatureStore featureStore, EventFactory eventFactory)
        {
            IList <FeatureRequestEvent> prereqEvents = new List <FeatureRequestEvent>();
            EvalResult evalResult = new EvalResult(null, null, prereqEvents);

            if (user == null || user.Key == null)
            {
                Log.WarnFormat("User or user key is null when evaluating flag: {0} returning null",
                               Key);

                return(evalResult);
            }

            if (On)
            {
                evalResult = Evaluate(user, featureStore, prereqEvents, eventFactory);
                if (evalResult.Result != null)
                {
                    return(evalResult);
                }
            }
            evalResult.Variation = OffVariation;
            evalResult.Result    = OffVariationValue;
            return(evalResult);
        }
示例#2
0
 internal PollingProcessor(Configuration config, FeatureRequestor featureRequestor, IFeatureStore featureStore)
 {
     _config           = config;
     _featureRequestor = featureRequestor;
     _featureStore     = featureStore;
     _initTask         = new TaskCompletionSource <bool>();
 }
示例#3
0
 public IUpdateProcessor CreateUpdateProcessor(Configuration config, IFeatureStore featureStore, IDiagnosticStore diagnosticStore)
 {
     if (config.Offline)
     {
         Log.Info("Starting Launchdarkly client in offline mode.");
         return(new NullUpdateProcessor());
     }
     else if (config.UseLdd)
     {
         Log.Info("Starting LaunchDarkly in LDD mode. Skipping direct feature retrieval.");
         return(new NullUpdateProcessor());
     }
     else
     {
         FeatureRequestor requestor = new FeatureRequestor(config);
         if (config.IsStreamingEnabled)
         {
             return(new StreamProcessor(config, requestor, featureStore, null, diagnosticStore));
         }
         else
         {
             Log.Warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support");
             return(new PollingProcessor(config, requestor, featureStore));
         }
     }
 }
示例#4
0
        private int?EvaluateIndex(User user, IFeatureStore store)
        {
            // Check to see if targets match
            foreach (var target in Targets)
            {
                foreach (var v in target.Values)
                {
                    if (v.Equals(user.Key))
                    {
                        return(target.Variation);
                    }
                }
            }

            // Now walk through the rules and see if any match
            foreach (Rule rule in Rules)
            {
                if (rule.MatchesUser(user, store))
                {
                    return(rule.VariationIndexForUser(user, Key, Salt));
                }
            }

            // Walk through the fallthrough and see if it matches
            return(Fallthrough.VariationIndexForUser(user, Key, Salt));
        }
示例#5
0
        public FileDataSource(IFeatureStore featureStore, List <string> paths, bool autoUpdate, TimeSpan pollInterval,
                              Func <string, object> alternateParser)
        {
            _featureStore = featureStore;
            _paths        = new List <string>(paths);
            _parser       = new FlagFileParser(alternateParser);
            if (autoUpdate)
            {
                try
                {
#if NETSTANDARD1_4 || NETSTANDARD1_6
                    _reloader = new FilePollingReloader(_paths, TriggerReload, pollInterval);
#else
                    _reloader = new FileWatchingReloader(_paths, TriggerReload);
#endif
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Unable to watch files for auto-updating: {0}", e);
                    _reloader = null;
                }
            }
            else
            {
                _reloader = null;
            }
        }
示例#6
0
 public ClientFeatureValueProvider(
     IFeatureStore featureStore,
     ICurrentClient currentClient)
     : base(featureStore)
 {
     CurrentClient = currentClient;
 }
示例#7
0
        public ConfigurationBuilder(Configuration copyFrom)
        {
            _allAttributesPrivate = copyFrom.AllAttributesPrivate;
            _baseUri                     = copyFrom.BaseUri;
            _diagnosticOptOut            = copyFrom.DiagnosticOptOut;
            _diagnosticRecordingInterval = copyFrom.DiagnosticRecordingInterval;
            _eventCapacity               = copyFrom.EventCapacity;
            _eventFlushInterval          = copyFrom.EventFlushInterval;
            _eventProcessorFactory       = copyFrom.EventProcessorFactory;
#pragma warning disable 618
            _eventSamplingInterval = copyFrom.EventSamplingInterval;
#pragma warning restore 618
            _eventsUri             = copyFrom.EventsUri;
            _featureStore          = copyFrom.FeatureStore;
            _featureStoreFactory   = copyFrom.FeatureStoreFactory;
            _httpClientHandler     = copyFrom.HttpClientHandler;
            _httpClientTimeout     = copyFrom.HttpClientTimeout;
            _inlineUsersInEvents   = copyFrom.InlineUsersInEvents;
            _isStreamingEnabled    = copyFrom.IsStreamingEnabled;
            _offline               = copyFrom.Offline;
            _pollingInterval       = copyFrom.PollingInterval;
            _privateAttributeNames = copyFrom.PrivateAttributeNames is null ? null :
                                     new HashSet <string>(copyFrom.PrivateAttributeNames);
            _readTimeout            = copyFrom.ReadTimeout;
            _reconnectTime          = copyFrom.ReconnectTime;
            _sdkKey                 = copyFrom.SdkKey;
            _startWaitTime          = copyFrom.StartWaitTime;
            _streamUri              = copyFrom.StreamUri;
            _updateProcessorFactory = copyFrom.UpdateProcessorFactory;
            _useLdd                 = copyFrom.UseLdd;
            _userKeysCapacity       = copyFrom.UserKeysCapacity;
            _userKeysFlushInterval  = copyFrom.UserKeysFlushInterval;
            _wrapperName            = copyFrom.WrapperName;
            _wrapperVersion         = copyFrom.WrapperVersion;
        }
示例#8
0
        protected NewsViewModel(IMvxNavigationService navigation
                                , IMvxMessenger messenger
                                , INewsService news
                                , IReachabilityService reachability
                                , IFeatureStore featureStore
                                , IBrowserService browser
                                , IDialogService dialog)
        {
            _navigation   = navigation;
            _messenger    = messenger;
            _news         = news;
            _reachability = reachability;
            _featureStore = featureStore;
            _browser      = browser;
            _dialog       = dialog;

            _stories = new MvxObservableCollection <StoryItemViewModel>();

            ShowStoryCommand = new MvxAsyncCommand <StoryItemViewModel>(OnShowStory, item => item.Filled && item.Story.Type == ItemType.Story);
            RefreshCommand   = new MvxAsyncCommand(LoadStories);

            ShowSettingsCommand = new MvxAsyncCommand(() => _navigation.Navigate <SettingsViewModel>());

            _fillerToken = messenger.Subscribe <NewsItemMessage>(OnItemReceived);

            TabPresentation = featureStore.IsEnabled(Features.StoryTabPresentation);
        }
示例#9
0
        /// <summary>
        /// Creates a new client to connect to LaunchDarkly with a custom configuration, and a custom
        /// implementation of the analytics event processor. This constructor should only be used if you are
        /// overriding the default event-sending behavior.
        /// </summary>
        /// <param name="config">a client configuration object</param>
        /// <param name="eventStore">an event processor</param>
        public LdClient(Configuration config, IStoreEvents eventStore)
        {
            Log.InfoFormat("Starting LaunchDarkly Client {0}",
                           Configuration.Version);

            _configuration = config;
            _eventStore    = eventStore;
            _featureStore  = _configuration.FeatureStore;

            if (_configuration.Offline)
            {
                Log.Info("Starting Launchdarkly client in offline mode.");
                return;
            }

            var featureRequestor = new FeatureRequestor(config);

            if (_configuration.IsStreamingEnabled)
            {
                _updateProcessor = new StreamProcessor(config, featureRequestor, _featureStore);
            }
            else
            {
                Log.Warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support");
                _updateProcessor = new PollingProcessor(config, featureRequestor, _featureStore);
            }
            var initTask = _updateProcessor.Start();

            Log.InfoFormat("Waiting up to {0} milliseconds for LaunchDarkly client to start..",
                           _configuration.StartWaitTime.TotalMilliseconds);

            var unused = initTask.Wait(_configuration.StartWaitTime);
        }
示例#10
0
 public MockNewsViewModel(IMvxNavigationService navigation
                          , IMvxMessenger messenger
                          , INewsService news
                          , IReachabilityService reachability
                          , IFeatureStore featureStore
                          , IBrowserService browser
                          , IDialogService dialog)
     : base(navigation, messenger, news, reachability, featureStore, browser, dialog) =>
示例#11
0
 internal StreamProcessor(Configuration config, IFeatureRequestor featureRequestor, IFeatureStore featureStore)
 {
     _config           = config;
     _featureRequestor = featureRequestor;
     _featureStore     = featureStore;
     _initTask         = new TaskCompletionSource <bool>();
     _backOff          = new EventSource.ExponentialBackoffWithDecorrelation(_config.ReconnectTime, TimeSpan.FromMilliseconds(30000));
 }
示例#12
0
        public LdClient(Configuration config, IEventProcessor eventProcessor)
        {
            Log.InfoFormat("Starting LaunchDarkly Client {0}",
                           ServerSideClientEnvironment.Instance.Version);

            _configuration = config;

            if (eventProcessor == null)
            {
                _eventProcessor = (_configuration.EventProcessorFactory ??
                                   Components.DefaultEventProcessor).CreateEventProcessor(_configuration);
                _shouldDisposeEventProcessor = true;
            }
            else
            {
                _eventProcessor = eventProcessor;
                // The following line is for backward compatibility with the obsolete mechanism by which the
                // caller could pass in an IStoreEvents implementation instance that we did not create.  We
                // were not disposing of that instance when the client was closed, so we should continue not
                // doing so until the next major version eliminates that mechanism.  We will always dispose
                // of instances that we created ourselves from a factory.
                _shouldDisposeEventProcessor = false;
            }

            if (_configuration.FeatureStore == null)
            {
                _featureStore = (_configuration.FeatureStoreFactory ??
                                 Components.InMemoryFeatureStore).CreateFeatureStore();
                _shouldDisposeFeatureStore = true;
            }
            else
            {
                _featureStore = _configuration.FeatureStore;
                _shouldDisposeFeatureStore = false; // see previous comment
            }

            _updateProcessor = (_configuration.UpdateProcessorFactory ??
                                Components.DefaultUpdateProcessor).CreateUpdateProcessor(_configuration, _featureStore);

            var initTask = _updateProcessor.Start();

            if (!(_updateProcessor is NullUpdateProcessor))
            {
                Log.InfoFormat("Waiting up to {0} milliseconds for LaunchDarkly client to start..",
                               _configuration.StartWaitTime.TotalMilliseconds);
            }

            try
            {
                var unused = initTask.Wait(_configuration.StartWaitTime);
            }
            catch (AggregateException)
            {
                // StreamProcessor may throw an exception if initialization fails, because we want that behavior
                // in the Xamarin client. However, for backward compatibility we do not want to throw exceptions
                // from the LdClient constructor in the .NET client, so we'll just swallow this.
            }
        }
示例#13
0
        private LdClient MakeClient(IFeatureStore featureStore, MockEventProcessor ep)
        {
            Configuration config = Configuration.Default("secret")
                                   .WithFeatureStoreFactory(TestUtils.SpecificFeatureStore(featureStore))
                                   .WithEventProcessorFactory(TestUtils.SpecificEventProcessor(ep))
                                   .WithUpdateProcessorFactory(Components.NullUpdateProcessor);
            LdClient client = new LdClient(config);

            featureStore.Init(new Dictionary <IVersionedDataKind, IDictionary <string, IVersionedData> >());
            return(client);
        }
示例#14
0
        // Returning either a nil EvalResult or EvalResult.value indicates prereq failure/error.
        private EvalResult Evaluate(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events,
                                    EventFactory eventFactory)
        {
            var prereqOk = true;

            if (Prerequisites != null)
            {
                foreach (var prereq in Prerequisites)
                {
                    var        prereqFeatureFlag = featureStore.Get(VersionedDataKind.Features, prereq.Key);
                    EvalResult prereqEvalResult  = new EvalResult(null, null, events);
                    if (prereqFeatureFlag == null)
                    {
                        Log.ErrorFormat("Could not retrieve prerequisite flag: {0} when evaluating: {1}",
                                        prereq.Key,
                                        Key);
                        return(new EvalResult(null, null, events));
                    }
                    else if (prereqFeatureFlag.On)
                    {
                        prereqEvalResult = prereqFeatureFlag.Evaluate(user, featureStore, events, eventFactory);
                        try
                        {
                            if (prereqEvalResult.Variation != prereq.Variation)
                            {
                                prereqOk = false;
                            }
                        }
                        catch (EvaluationException e)
                        {
                            Log.WarnFormat("Error evaluating prerequisites: {0}",
                                           e,
                                           Util.ExceptionMessage(e));

                            prereqOk = false;
                        }
                    }
                    else
                    {
                        prereqOk = false;
                    }
                    //We don't short circuit and also send events for each prereq.
                    events.Add(eventFactory.NewPrerequisiteFeatureRequestEvent(prereqFeatureFlag,
                                                                               user, null, prereqEvalResult.Result, this));
                }
            }
            if (prereqOk)
            {
                int?   index  = EvaluateIndex(user, featureStore);
                JToken result = GetVariation(index);
                return(new EvalResult(index, result, events));
            }
            return(new EvalResult(null, null, events));
        }
示例#15
0
        public SettingsViewModel(IMvxNavigationService navigation, IBrowserService browser, IAppService app, IFeatureStore features)
        {
            _navigation               = navigation;
            _browser                  = browser;
            _features                 = features;
            ShowProjectSiteCommand    = new MvxAsyncCommand(OnShowProjectSite);
            ShowLicensesCommand       = new MvxAsyncCommand(OnShowLicenses);
            ShowFeatureTogglesCommand = new MvxAsyncCommand(OnShowFeatureToggles, () => features.IsEnabled(Features.ShowOverrideUi));

            VersionString = $"{app.Name} for {app.Platform} v{app.Version} ({app.BuildNumber})";
        }
示例#16
0
 internal bool MatchesUser(User user, IFeatureStore store)
 {
     foreach (var c in Clauses)
     {
         if (!c.MatchesUser(user, store))
         {
             return(false);
         }
     }
     return(true);
 }
示例#17
0
 internal StreamProcessor(Configuration config, IFeatureRequestor featureRequestor,
                          IFeatureStore featureStore, StreamManager.EventSourceCreator eventSourceCreator)
 {
     _streamManager = new StreamManager(this,
                                        MakeStreamProperties(config),
                                        config,
                                        ServerSideClientEnvironment.Instance,
                                        eventSourceCreator);
     _config           = config;
     _featureRequestor = featureRequestor;
     _featureStore     = featureStore;
 }
示例#18
0
        // Returning either a nil EvalResult or EvalResult.value indicates prereq failure/error.
        private JToken Evaluate(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events, Configuration config)
        {
            var prereqOk = true;

            if (Prerequisites != null)
            {
                foreach (var prereq in Prerequisites)
                {
                    var    prereqFeatureFlag = featureStore.Get(VersionedDataKind.Features, prereq.Key);
                    JToken prereqEvalResult  = null;
                    if (prereqFeatureFlag == null)
                    {
                        Log.ErrorFormat("Could not retrieve prerequisite flag: {0} when evaluating: {1}",
                                        prereq.Key,
                                        Key);
                        return(null);
                    }
                    else if (prereqFeatureFlag.On)
                    {
                        prereqEvalResult = prereqFeatureFlag.Evaluate(user, featureStore, events, config);
                        try
                        {
                            JToken variation = prereqFeatureFlag.GetVariation(prereq.Variation);
                            if (prereqEvalResult == null || variation == null || !prereqEvalResult.Equals(variation))
                            {
                                prereqOk = false;
                            }
                        }
                        catch (EvaluationException e)
                        {
                            Log.WarnFormat("Error evaluating prerequisites: {0}",
                                           e,
                                           Util.ExceptionMessage(e));

                            prereqOk = false;
                        }
                    }
                    else
                    {
                        prereqOk = false;
                    }
                    //We don't short circuit and also send events for each prereq.
                    events.Add(new FeatureRequestEvent(prereqFeatureFlag.Key, EventUser.FromUser(user, config),
                                                       prereqEvalResult, null, prereqFeatureFlag.Version, prereq.Key));
                }
            }
            if (prereqOk)
            {
                return(GetVariation(EvaluateIndex(user, featureStore)));
            }
            return(null);
        }
        private Action MakeConcurrentModifier(IFeatureStore store, string key, params int[] versionsToWrite)
        {
            var i = 0;

            return(() =>
            {
                if (i < versionsToWrite.Length)
                {
                    store.Upsert(TestEntity.Kind, new TestEntity(key, versionsToWrite[i]));
                    i++;
                }
            });
        }
示例#20
0
        public void Setup()
        {
            var n = new NameValueCollection();

            n.Add("features.FeatureA", "true");
            n.Add("features.FeatureB", "True");
            n.Add("features.FeatureC", "false");
            n.Add("features.FeatureD", "False");
            n.Add("features.FeatureE", "1");
            n.Add("features.FeatureF", "0");
            n.Add("features.FeatureG", "abc");
            n.Add("features.FeatureH", "on");
            n.Add("features.FeatureI", "yes");
            globalFeatureStore = new CachingFeatureStore(new AppSettingsFeatureStore(n));
        }
示例#21
0
        public async Task Setup()
        {
            StartZooKeeper();
            var zk = new ZooKeeper("127.0.0.1:2181", 60000, null);

            await DeleteRecursive(zk, "/FeatureFlags", "features");
            await CreateIfNotExist(zk, "/FeatureFlags/features/featureA", "true");
            await CreateIfNotExist(zk, "/FeatureFlags/features/featureB", "false");
            await CreateIfNotExist(zk, "/FeatureFlags/features/featureC", "true");
            await CreateIfNotExist(zk, "/FeatureFlags/features/featureD", "true");

            await zk.closeAsync();

            featureStore = new CachingFeatureStore(new ZooKeeperFeatureStore("127.0.0.1:2181/FeatureFlags"));
        }
示例#22
0
        // Returning either a nil EvalResult or EvalResult.value indicates prereq failure/error.
        private JToken Evaluate(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events)
        {
            var prereqOk = true;

            if (Prerequisites != null)
            {
                foreach (var prereq in Prerequisites)
                {
                    var    prereqFeatureFlag = featureStore.Get(prereq.Key);
                    JToken prereqEvalResult  = null;
                    if (prereqFeatureFlag == null)
                    {
                        Logger.LogError("Could not retrieve prerequisite flag: " + prereq.Key + " when evaluating: " +
                                        Key);
                        return(null);
                    }
                    else if (prereqFeatureFlag.On)
                    {
                        prereqEvalResult = prereqFeatureFlag.Evaluate(user, featureStore, events);
                        try
                        {
                            JToken variation = prereqFeatureFlag.GetVariation(prereq.Variation);
                            if (prereqEvalResult == null || variation == null || !prereqEvalResult.Equals(variation))
                            {
                                prereqOk = false;
                            }
                        }
                        catch (EvaluationException e)
                        {
                            Logger.LogWarning("Error evaluating prerequisites: " + e.Message, e);
                            prereqOk = false;
                        }
                    }
                    else
                    {
                        prereqOk = false;
                    }
                    //We don't short circuit and also send events for each prereq.
                    events.Add(new FeatureRequestEvent(prereqFeatureFlag.Key, user, prereqEvalResult, null,
                                                       prereqFeatureFlag.Version, prereq.Key));
                }
            }
            if (prereqOk)
            {
                return(GetVariation(EvaluateIndex(user)));
            }
            return(null);
        }
示例#23
0
        internal EvalResult Evaluate(User user, IFeatureStore featureStore, EventFactory eventFactory)
        {
            IList <FeatureRequestEvent> prereqEvents = new List <FeatureRequestEvent>();

            if (user == null || user.Key == null)
            {
                Log.WarnFormat("User or user key is null when evaluating flag: {0} returning null",
                               Key);

                return(new EvalResult(
                           new EvaluationDetail <JToken>(null, null, new EvaluationReason.Error(EvaluationErrorKind.USER_NOT_SPECIFIED)),
                           prereqEvents));
            }
            var details = Evaluate(user, featureStore, prereqEvents, eventFactory);

            return(new EvalResult(details, prereqEvents));
        }
示例#24
0
        private EvaluationDetail <JToken> Evaluate(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events,
                                                   EventFactory eventFactory)
        {
            if (!On)
            {
                return(GetOffValue(EvaluationReason.Off.Instance));
            }

            var prereqFailureReason = CheckPrerequisites(user, featureStore, events, eventFactory);

            if (prereqFailureReason != null)
            {
                return(GetOffValue(prereqFailureReason));
            }

            // Check to see if targets match
            if (Targets != null)
            {
                foreach (var target in Targets)
                {
                    foreach (var v in target.Values)
                    {
                        if (user.Key == v)
                        {
                            return(GetVariation(target.Variation, EvaluationReason.TargetMatch.Instance));
                        }
                    }
                }
            }
            // Now walk through the rules and see if any match
            if (Rules != null)
            {
                for (int i = 0; i < Rules.Count; i++)
                {
                    Rule rule = Rules[i];
                    if (rule.MatchesUser(user, featureStore))
                    {
                        return(GetValueForVariationOrRollout(rule, user,
                                                             new EvaluationReason.RuleMatch(i, rule.Id)));
                    }
                }
            }
            // Walk through the fallthrough and see if it matches
            return(GetValueForVariationOrRollout(Fallthrough, user, EvaluationReason.Fallthrough.Instance));
        }
示例#25
0
 internal bool MatchesUser(User user, IFeatureStore store)
 {
     if (Op == "segmentMatch")
     {
         foreach (var value in Values)
         {
             Segment segment = store.Get(VersionedDataKind.Segments, value.Value <string>());
             if (segment != null && segment.MatchesUser(user))
             {
                 return(MaybeNegate(true));
             }
         }
         return(MaybeNegate(false));
     }
     else
     {
         return(MatchesUserNoSegments(user));
     }
 }
示例#26
0
        public LdClient(Configuration config, IStoreEvents eventStore)
        {
            Logger.LogInformation("Starting LaunchDarkly Client " + Configuration.Version);
            _configuration = config;
            _eventStore    = eventStore;
            _featureStore  = config.FeatureStore;

            if (_configuration.Offline)
            {
                Logger.LogInformation("Starting Launchdarkly client in offline mode.");
                return;
            }

            var featureRequestor = new FeatureRequestor(config);

            _updateProcessor = new PollingProcessor(config, featureRequestor, _featureStore);
            var initTask = _updateProcessor.Start();

            Logger.LogInformation("Waiting up to " + _configuration.StartWaitTime.TotalMilliseconds +
                                  " milliseconds for LaunchDarkly client to start..");
            var unused = initTask.Task.Wait(_configuration.StartWaitTime);
        }
示例#27
0
        internal EvalResult Evaluate(User user, IFeatureStore featureStore)
        {
            IList <FeatureRequestEvent> prereqEvents = new List <FeatureRequestEvent>();
            EvalResult evalResult = new EvalResult(null, prereqEvents);

            if (user == null || user.Key == null)
            {
                Logger.LogWarning("User or user key is null when evaluating flag: " + Key + " returning null");
                return(evalResult);
            }

            if (On)
            {
                evalResult.Result = Evaluate(user, featureStore, prereqEvents);
                if (evalResult.Result != null)
                {
                    return(evalResult);
                }
            }
            evalResult.Result = OffVariationValue;
            return(evalResult);
        }
示例#28
0
 // Checks prerequisites if any; returns null if successful, or an EvaluationReason if we have to
 // short-circuit due to a prerequisite failure.
 private EvaluationReason CheckPrerequisites(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events,
                                             EventFactory eventFactory)
 {
     if (Prerequisites == null || Prerequisites.Count == 0)
     {
         return(null);
     }
     foreach (var prereq in Prerequisites)
     {
         var prereqOk          = true;
         var prereqFeatureFlag = featureStore.Get(VersionedDataKind.Features, prereq.Key);
         if (prereqFeatureFlag == null)
         {
             Log.ErrorFormat("Could not retrieve prerequisite flag \"{0}\" when evaluating \"{1}\"",
                             prereq.Key, Key);
             prereqOk = false;
         }
         else
         {
             var prereqEvalResult = prereqFeatureFlag.Evaluate(user, featureStore, events, eventFactory);
             // 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 || prereqEvalResult.VariationIndex == null || prereqEvalResult.VariationIndex.Value != prereq.Variation)
             {
                 prereqOk = false;
             }
             events.Add(eventFactory.NewPrerequisiteFeatureRequestEvent(prereqFeatureFlag, user,
                                                                        prereqEvalResult, this));
         }
         if (!prereqOk)
         {
             return(new EvaluationReason.PrerequisiteFailed(prereq.Key));
         }
     }
     return(null);
 }
示例#29
0
 public EditionFeatureValueProvider(IFeatureStore featureStore, ICurrentPrincipalAccessor principalAccessor)
     : base(featureStore)
 {
     PrincipalAccessor = principalAccessor;
 }
示例#30
0
 public DefaultValueFeatureValueProvider(IFeatureStore settingStore)
     : base(settingStore)
 {
 }