internal EntitySelectors(
            IComparer <TEntity> sortComparer
            )
        {
            SelectIds = CreateSelector(
                (EntityState <TEntity, TKey> entityState) => entityState.Ids
                );

            SelectCollection = CreateSelector(
                (EntityState <TEntity, TKey> entityState) => entityState.Collection
                );

            SelectEntities = CreateSelector(
                SelectCollection,
                collection =>
            {
                var result = collection
                             .Select(x => x.Value)
                             .ToList();

                if (sortComparer != null)
                {
                    result.Sort(sortComparer);
                }

                return(result);
            }
                );

            SelectCount = CreateSelector(
                SelectCollection,
                collection => collection.Count
                );
        }
Beispiel #2
0
 public MemoizedSelector(
     ISelectorWithoutProps <TInput, TSelectorResult> selector,
     Func <TSelectorResult, TOutput> projectorFunction
     )
 {
     Selector          = selector;
     ProjectorFunction = projectorFunction;
 }
Beispiel #3
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());
        }
Beispiel #4
0
 /// <summary>
 /// Create a new selector based on the previous ones.
 /// </summary>
 /// <typeparam name="TState">State to consume.</typeparam>
 /// <typeparam name="TSelectorResult1">Result of the previous selector.</typeparam>
 /// <typeparam name="TFinalResult">Result of the final selector.</typeparam>
 /// <param name="selector1">First selector.</param>
 /// <param name="projectorFunction">Selector that combines all values from the previous selectors.</param>
 /// <returns>A new selector using the previous ones.</returns>
 public static ISelectorWithoutProps <TState, TFinalResult> CreateSelector <TState, TSelectorResult1, TFinalResult>(
     ISelectorWithoutProps <TState, TSelectorResult1> selector1,
     Func <TSelectorResult1, TFinalResult> projectorFunction
     )
 {
     return(new MemoizedSelector <TState, TSelectorResult1, TFinalResult>(
                selector1,
                projectorFunction
                ));
 }
Beispiel #5
0
 /// <summary>
 /// Combine multiple selectors.
 /// </summary>
 /// <typeparam name="TState">Type of the root state.</typeparam>
 /// <typeparam name="TSelectorResult1">Type of the result of the first selector.</typeparam>
 /// <typeparam name="TSelectorResult2">Type of the result of the second selector.</typeparam>
 /// <param name="selector1">First selector.</param>
 /// <param name="selector2">Second selector.</param>
 /// <returns></returns>
 public static ISelectorWithoutProps <TState, Tuple <TSelectorResult1, TSelectorResult2> > CombineSelectors <TState, TSelectorResult1, TSelectorResult2>(
     ISelectorWithoutProps <TState, TSelectorResult1> selector1,
     ISelectorWithoutProps <TState, TSelectorResult2> selector2
     )
 {
     return(new MemoizedSelector <TState, TSelectorResult1, TSelectorResult2, Tuple <TSelectorResult1, TSelectorResult2> >(
                selector1,
                selector2,
                (result1, result2) => Tuple.Create(result1, result2)
                ));
 }
Beispiel #6
0
        /// <summary>
        /// Creates an explicit state lens used for nested state reducers.
        /// </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">Selector to access the feature state from state.</param>
        /// <param name="stateReducer">The reducer function to update the nested <typeparamref name="TFeatureState"/> in the <typeparamref name="TState"/>.</param>
        /// <returns>An explicit state lens.</returns>
        public static IStateLens <TState, TFeatureState> CreateSubReducers <TState, TFeatureState>(
            ISelectorWithoutProps <TState, TFeatureState> featureSelector,
            Func <TState, TFeatureState, TState> stateReducer
            )
            where TState : class, new()
            where TFeatureState : class, new()
        {
            var selector = new Func <TState, TFeatureState>(state => featureSelector.Apply(state));

            return(new ExplicitStateLens <TState, TFeatureState>(selector, stateReducer));
        }
Beispiel #7
0
 /// <summary>
 /// Combine multiple selectors.
 /// </summary>
 /// <typeparam name="TState">Type of the root state.</typeparam>
 /// <typeparam name="TSelectorResult1">Type of the result of the first selector.</typeparam>
 /// <typeparam name="TSelectorResult2">Type of the result of the second selector.</typeparam>
 /// <typeparam name="TSelectorResult3">Type of the result of the third selector.</typeparam>
 /// <typeparam name="TSelectorResult4">Type of the result of the fourth selector.</typeparam>
 /// <param name="selector1">First selector.</param>
 /// <param name="selector2">Second selector.</param>
 /// <param name="selector3">Third selector.</param>
 /// <param name="selector4">Fourth selector.</param>
 /// <returns></returns>
 public static ISelectorWithoutProps <TState, Tuple <TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4> > CombineSelectors <TState, TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4>(
     ISelectorWithoutProps <TState, TSelectorResult1> selector1,
     ISelectorWithoutProps <TState, TSelectorResult2> selector2,
     ISelectorWithoutProps <TState, TSelectorResult3> selector3,
     ISelectorWithoutProps <TState, TSelectorResult4> selector4
     )
 {
     return(new MemoizedSelector <TState, TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4, Tuple <TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4> >(
                selector1,
                selector2,
                selector3,
                selector4,
                (result1, result2, result3, result4) => Tuple.Create(result1, result2, result3, result4)
                ));
 }
Beispiel #8
0
 /// <summary>
 /// Create a new selector based on the previous ones.
 /// </summary>
 /// <typeparam name="TState">State to consume.</typeparam>
 /// <typeparam name="TSelectorResult1">Result of the first previous selector.</typeparam>
 /// <typeparam name="TSelectorResult2">Result of the second previous selector.</typeparam>
 /// <typeparam name="TSelectorResult3">Result of the third previous selector.</typeparam>
 /// <typeparam name="TSelectorResult4">Result of the fourth previous selector.</typeparam>
 /// <typeparam name="TFinalResult">Result of the final selector.</typeparam>
 /// <param name="selector1">First selector.</param>
 /// <param name="selector2">Second selector.</param>
 /// <param name="selector3">Third selector.</param>
 /// <param name="selector4">Fourth selector.</param>
 /// <param name="projectorFunction">Selector that combines all values from the previous selectors.</param>
 /// <returns>A new selector using the previous ones.</returns>
 public static ISelectorWithoutProps <TState, TFinalResult> CreateSelector <TState, TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4, TFinalResult>(
     ISelectorWithoutProps <TState, TSelectorResult1> selector1,
     ISelectorWithoutProps <TState, TSelectorResult2> selector2,
     ISelectorWithoutProps <TState, TSelectorResult3> selector3,
     ISelectorWithoutProps <TState, TSelectorResult4> selector4,
     Func <TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4, TFinalResult> projectorFunction
     )
 {
     return(new MemoizedSelector <TState, TSelectorResult1, TSelectorResult2, TSelectorResult3, TSelectorResult4, TFinalResult>(
                selector1,
                selector2,
                selector3,
                selector4,
                projectorFunction
                ));
 }
Beispiel #9
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());
        }
Beispiel #10
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));
 }
 /// <summary>
 /// Get selectors for the specified <see cref="EntityState{TEntity, TKey}"/>.
 /// </summary>
 /// <typeparam name="TInput">Part of the state used to create selectors.</typeparam>
 /// <param name="selectEntityState">Function used to select <see cref="EntityState{TEntity, TKey}"/> from the <typeparamref name="TInput"/>.</param>
 /// <returns>A new Entity Selectors.</returns>
 public EntitySelectors <TInput, TEntity, TKey> GetSelectors <TInput>(
     ISelectorWithoutProps <TInput, EntityState <TEntity, TKey> > selectEntityState
     )
 {
     return(new EntitySelectors <TInput, TEntity, TKey>(selectEntityState, SortComparer));
 }
Beispiel #12
0
 public IObservable <TResult> Select <TResult>(ISelectorWithoutProps <TState, TResult> selector, string?optionsStr = null)
 {
     SelectInvoked = true;
     return(selector.Apply(_stateSubject));
 }