Exemplo n.º 1
0
        /// <summary>
        /// Creates an implicit state lens used for nested state reducers.
        /// If possible, try to create an explicit state lens using <see cref="CreateSubReducers"/> function overrides.
        /// </summary>
        /// <typeparam name="TState">Type of the state to update.</typeparam>
        /// <typeparam name="TFeatureState">Type of the feature state which will be the target of reducers.</typeparam>
        /// <param name="featureSelector"></param>
        /// <returns>An implicit state lens.</returns>
        public static IStateLens <TState, TFeatureState> CreateSubReducers <TState, TFeatureState>(ISelectorWithoutProps <TState, TFeatureState> featureSelector)
            where TState : class, new()
            where TFeatureState : class, new()
        {
            var selector = new Func <TState, TFeatureState>(state => featureSelector.Apply(state));

            return(new ImplicitStateLens <TState, TFeatureState>(selector));
        }
Exemplo n.º 2
0
        public static On <TState>[] CreateSubReducers <TState, TFeatureState>(
            On <TFeatureState>[] featureReducers,
            ISelectorWithoutProps <TState, TFeatureState?> selectFeature
            )
            where TState : class, new()
            where TFeatureState : class, new()
        {
            var parentStateProperties = typeof(TState).GetProperties();

            return(featureReducers
                   .Select(r =>
            {
                return new On <TState>
                {
                    Reduce = (state, action) =>
                    {
                        if (r?.Reduce == null)
                        {
                            return state;
                        }

                        var featureState = selectFeature.Apply(state);

                        if (featureState == null)
                        {
                            return state;
                        }

                        var reducerResult = r.Reduce(featureState, action);

                        if (featureState.IsDeepEqual(reducerResult))
                        {
                            return state;
                        }

                        var featureProperty = parentStateProperties
                                              .SingleOrDefault(p =>
                        {
                            return p.GetValue(state) == featureState;
                        });

                        if (featureProperty == null)
                        {
                            throw new NotSupportedException(
                                $"A sub-reducer cannot find the feature reducer of `{typeof(TFeatureState).Name}` inside `{typeof(TState).Name}`."
                                );
                        }

                        var stateCopy = state.Copy();
                        featureProperty.SetValue(stateCopy, reducerResult);

                        return stateCopy;
                    },
                    Types = r.Types
                };
            })
                   .ToArray());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Create a sub-reducers, for features-like purpose.
        /// </summary>
        /// <typeparam name="TState">Type of the root state.</typeparam>
        /// <typeparam name="TFeatureState">Type of the feature state.</typeparam>
        /// <param name="featureReducers">Reducers that directly use the feature state.</param>
        /// <param name="selectFeature">Select the feature from the root state.</param>
        /// <returns>Returns reducers targeting the root state.</returns>
        public static On <TState>[] CreateSubReducers <TState, TFeatureState>(
            On <TFeatureState>[] featureReducers,
            ISelectorWithoutProps <TState, TFeatureState> selectFeature
            )
            where TState : class, new()
            where TFeatureState : class, new()
        {
            var selectFeatureType = selectFeature.GetType();

            var selectFeatureInputType  = selectFeatureType.GenericTypeArguments[0];
            var selectFeatureOutputType = selectFeatureType.GenericTypeArguments[1];

            var featureProperty = selectFeatureInputType.GetProperties()
                                  .Single(p => p.PropertyType.FullName == selectFeatureOutputType.FullName);

            return(featureReducers
                   .Select(r =>
            {
                return new On <TState>
                {
                    Reduce = (state, action) =>
                    {
                        var featureState = selectFeature.Apply(state);
                        var reducerResult = r.Reduce(featureState, action);

                        if (IsDeepEqual(featureState, reducerResult))
                        {
                            return state;
                        }

                        var stateCopy = state.Copy();
                        featureProperty.SetValue(stateCopy, reducerResult);

                        return stateCopy;
                    },
                    Types = r.Types
                };
            })
                   .ToArray());
        }
Exemplo n.º 4
0
 /// <summary>
 /// Select a value derived from the state of the store.
 /// </summary>
 /// <typeparam name="TResult">The type of the selector result.</typeparam>
 /// <param name="selector">
 /// The mapping function that can be applied to get the desired partial state of type <typeparamref name="TResult"/> from an instance of <typeparamref name="TState"/>.
 /// </param>
 /// <returns></returns>
 public IObservable <TResult> Select <TResult>(ISelectorWithoutProps <TState, TResult> selector)
 {
     return(selector.Apply(_stateSubject));
 }
Exemplo n.º 5
0
 public IObservable <TResult> Select <TResult>(ISelectorWithoutProps <TState, TResult> selector, string?optionsStr = null)
 {
     SelectInvoked = true;
     return(selector.Apply(_stateSubject));
 }