From 80188be596a3118ecd56408e76a2407c6ebb4d5b Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 22 Nov 2020 21:50:38 +0000 Subject: [PATCH 1/5] Update to .Net 5 and make store accept reference types. --- .../NetRx.Store.Monitor.Extension.csproj | 2 +- src/NetRx.Store.Monitor.Extension/app.config | 8 ++-- .../NetRx.Store.Monitor.Shared.csproj | 2 +- .../NetRx.Store.Tests.csproj | 16 +++++--- .../State/Actions/TestStateActions.cs | 9 +++++ .../State/Reducers/TestStateReducer.cs | 7 ++++ .../State/States/TestState.cs | 13 ++++++- src/NetRx.Store.Tests/Store/StoreTest.cs | 39 +++++++++++++------ src/NetRx.Store/NetRx.Store.csproj | 10 ++--- src/NetRx.Store/Store/StateWrapper.cs | 20 ++++++++-- src/NetRx.Store/Store/Store.cs | 8 +++- 11 files changed, 99 insertions(+), 35 deletions(-) diff --git a/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj b/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj index 85f91a5..94fbea6 100644 --- a/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj +++ b/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj @@ -26,7 +26,7 @@ Properties NetRx.Store.Monitor.Extension NetRx.Store.Monitor.Extension - v4.7 + v4.8 true true true diff --git a/src/NetRx.Store.Monitor.Extension/app.config b/src/NetRx.Store.Monitor.Extension/app.config index 6da7fbe..c764f53 100644 --- a/src/NetRx.Store.Monitor.Extension/app.config +++ b/src/NetRx.Store.Monitor.Extension/app.config @@ -1,11 +1,11 @@ - + - - + + - + diff --git a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj index c03bcbd..a93e52c 100644 --- a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj +++ b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + netstandard2.1 true Key.snk diff --git a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj index 3d910bd..1a70471 100644 --- a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj +++ b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj @@ -1,15 +1,19 @@ - netcoreapp2.0 + net5.0 - - - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/NetRx.Store.Tests/State/Actions/TestStateActions.cs b/src/NetRx.Store.Tests/State/Actions/TestStateActions.cs index 0a91cbb..8e566fa 100644 --- a/src/NetRx.Store.Tests/State/Actions/TestStateActions.cs +++ b/src/NetRx.Store.Tests/State/Actions/TestStateActions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; + using NetRx.Store; namespace NetRx.Store.Tests.State.TestStateActions @@ -14,4 +15,12 @@ public SetItemsAction(List payload) : base(payload) { } } + + public class SetReferenceObjectAction : Action + { + public SetReferenceObjectAction(ReferenceObect payload) :base(payload) + { + + } + } } diff --git a/src/NetRx.Store.Tests/State/Reducers/TestStateReducer.cs b/src/NetRx.Store.Tests/State/Reducers/TestStateReducer.cs index 8c0caca..b067b7c 100644 --- a/src/NetRx.Store.Tests/State/Reducers/TestStateReducer.cs +++ b/src/NetRx.Store.Tests/State/Reducers/TestStateReducer.cs @@ -21,6 +21,13 @@ public TestState Reduce(TestState state, TestStateActions.SetItemsAction action) state.Items = action.Payload.ToImmutableList(); return state; } + + public TestState Reduce(TestState state, TestStateActions.SetReferenceObjectAction action) + { + ReduceCalls.Add(action.GetType().FullName); + state.ReferenceObect = action.Payload; + return state; + } } public class SecondaryTestStateReducer : Reducer diff --git a/src/NetRx.Store.Tests/State/States/TestState.cs b/src/NetRx.Store.Tests/State/States/TestState.cs index 93cc2e5..fbd25e1 100644 --- a/src/NetRx.Store.Tests/State/States/TestState.cs +++ b/src/NetRx.Store.Tests/State/States/TestState.cs @@ -25,6 +25,13 @@ public struct SubState }; } + public class ReferenceObect + { + public string Name { get; set; } + + public string Description { get; set; } + } + public struct TestState { public int Id { get; set; } @@ -39,13 +46,17 @@ public struct TestState public ImmutableList Items { get; set; } + public ReferenceObect ReferenceObect { get;set; } + public static TestState Initial => new TestState { Id = 1, Name = "empty_name", Amount = 0.7m, IsEnabled = true, - SubState = SubState.Initial + SubState = SubState.Initial, + ReferenceObect = new ReferenceObect() + }; } diff --git a/src/NetRx.Store.Tests/Store/StoreTest.cs b/src/NetRx.Store.Tests/Store/StoreTest.cs index 22afc53..9340776 100644 --- a/src/NetRx.Store.Tests/Store/StoreTest.cs +++ b/src/NetRx.Store.Tests/Store/StoreTest.cs @@ -4,8 +4,11 @@ using NetRx.Store.Tests.State.Effects; using NetRx.Store.Tests.State.Reducers; using NetRx.Store.Tests.State.TestStateActions; + +using System; using System.Collections.Generic; using System.Linq; + using Xunit; namespace NetRx.Store.Tests @@ -24,18 +27,6 @@ public void WithState_Should_Throw_InvalidStateTypeException_When_Reference_stat Assert.Contains(nameof(InvalidTypeState), exception.Message); } - [Fact] - public void WithState_Should_Throw_InvalidStatePropertyTypeException_When_Reference_property_type_passed() - { - var exception = Record.Exception( - () => Store.Create().WithState(new InvalidPropertyTypeState(), new InvalidPropertyTypeStateReducer()) - ); - - Assert.NotNull(exception); - Assert.IsType(exception); - Assert.Contains(nameof(InvalidPropertyTypeState.Model), exception.Message); - } - [Fact] public void WithState_Should_Throw_InvalidStatePropertyTypeException_When_not_Immutable_collection_passed() { @@ -155,5 +146,29 @@ public void Dispatch_Should_call_Reducer_Reduce_and_Effect_Invoke_method_When_ca Assert.Single(reducer.ReduceCalls.Where(c => c == typeof(SetItemsAction).FullName)); Assert.Equal(1, effect.CallCount); } + + [Fact] + public void Dispatch_Should_call_Reducer_Reduce_and_observable_should_invoke() + { + var reducer = new TestStateReducer(); + var store = Store.Create() + .WithState(TestState.Initial, reducer); + + var newObject = new ReferenceObect(); + ReferenceObect selectedObect = null; + + var disposable = store.Select(f=> f.ReferenceObect) + .Subscribe(f => selectedObect = f); + + store.Dispatch(new SetReferenceObjectAction(newObject)); + + disposable.Dispose(); + + Assert.Same(newObject, selectedObect); + + + } + + } } diff --git a/src/NetRx.Store/NetRx.Store.csproj b/src/NetRx.Store/NetRx.Store.csproj index 70002c8..b05a364 100644 --- a/src/NetRx.Store/NetRx.Store.csproj +++ b/src/NetRx.Store/NetRx.Store.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.1 NetRx NetRx.Store 2.0.0 @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/src/NetRx.Store/Store/StateWrapper.cs b/src/NetRx.Store/Store/StateWrapper.cs index 6517252..4cd4605 100644 --- a/src/NetRx.Store/Store/StateWrapper.cs +++ b/src/NetRx.Store/Store/StateWrapper.cs @@ -10,6 +10,7 @@ namespace NetRx.Store internal sealed class StateWrapper { internal const string EnumerableFieldMarker = "#"; + internal const string ReferenceFieldMarker = "*"; private static readonly Dictionary>> _gettersCache = new Dictionary>>(); @@ -51,6 +52,8 @@ private void BuildGetters(Type type, string prefix) { var isString = p.PropertyType == stringType; var isEnumerable = p.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null && !isString; + var isReferenceType = p.PropertyType.IsClass && !isString || (p.PropertyType.IsInterface && p.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) == null); + if (isEnumerable) { var hasImmutableInterface = p.PropertyType @@ -65,10 +68,12 @@ private void BuildGetters(Type type, string prefix) throw new InvalidStatePropertyTypeException( $"'{p.Name}' cannot have reference type '{nonValueType.FullName}'. Should have 'struct' type"); } - else if (!p.PropertyType.IsValueType && + else if (!isReferenceType && + !p.PropertyType.IsValueType && !isString && !isEnumerable) { + throw new InvalidStatePropertyTypeException($"'{p.Name}' property of {prefix} cannot have reference type. Should have 'struct' type"); } @@ -80,7 +85,11 @@ private void BuildGetters(Type type, string prefix) wrappedObjectParameter ); - string name = isEnumerable ? $"{prefix}.{p.Name}{EnumerableFieldMarker}" : $"{prefix}.{p.Name}"; + string name = isEnumerable + ? $"{prefix}.{p.Name}{EnumerableFieldMarker}" + : isReferenceType + ? $"{prefix}.{p.Name}{ReferenceFieldMarker}" + : $"{prefix}.{p.Name}"; _gettersCache[OriginalTypeName].Add(name, getExpression.Compile()); @@ -94,7 +103,11 @@ private void BuildGetters(Type type, string prefix) public object Get(string name) { - var key = _gettersCache[OriginalTypeName].ContainsKey(name) ? name : $"{name}{EnumerableFieldMarker}"; + var key = _gettersCache[OriginalTypeName].ContainsKey(name) + ? name + : _gettersCache[OriginalTypeName].ContainsKey($"{name}{EnumerableFieldMarker}") + ? $"{name}{EnumerableFieldMarker}" + : $"{name}{ReferenceFieldMarker}"; var propNamePart = key.Substring(OriginalTypeName.Length); var pointIndex = propNamePart.LastIndexOf('.'); @@ -124,6 +137,7 @@ public object Get(string name) public bool HasGeter(string name) => _gettersCache[OriginalTypeName].ContainsKey(name) || _gettersCache[OriginalTypeName].ContainsKey($"{name}{EnumerableFieldMarker}") || + _gettersCache[OriginalTypeName].ContainsKey($"{name}{ReferenceFieldMarker}") || string.Equals(name, OriginalTypeName); public object Original { get; private set; } diff --git a/src/NetRx.Store/Store/Store.cs b/src/NetRx.Store/Store/Store.cs index bf494a9..13ccda9 100644 --- a/src/NetRx.Store/Store/Store.cs +++ b/src/NetRx.Store/Store/Store.cs @@ -184,10 +184,14 @@ private void DetectChanges(List<(string, StateWrapper)> modifiedStates) var hasChanges = field.EndsWith(StateWrapper.EnumerableFieldMarker, StringComparison.InvariantCulture) ? !Equals(newValue?.GetHashCode(), prevValue?.GetHashCode()) - : !Equals(newValue, prevValue); + : field.EndsWith(StateWrapper.ReferenceFieldMarker, StringComparison.InvariantCulture) + ? !ReferenceEquals(newValue,prevValue) + : !Equals(newValue, prevValue); if (hasChanges) { - NotifySubscribers(currState, field.Replace(StateWrapper.EnumerableFieldMarker, string.Empty)); + NotifySubscribers(currState, + field.Replace(StateWrapper.EnumerableFieldMarker, string.Empty) + .Replace(StateWrapper.ReferenceFieldMarker, string.Empty)); } } } From a12def631f2d19b7f15b1aff192b03fbeecc7587 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 22 Nov 2020 21:52:28 +0000 Subject: [PATCH 2/5] Up Version Numbers --- src/NetRx.Store.Monitor.Extension/Properties/AssemblyInfo.cs | 4 ++-- .../NetRx.Store.Monitor.Shared.csproj | 2 +- src/NetRx.Store/NetRx.Store.csproj | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NetRx.Store.Monitor.Extension/Properties/AssemblyInfo.cs b/src/NetRx.Store.Monitor.Extension/Properties/AssemblyInfo.cs index 3ee5b06..d39a6a8 100644 --- a/src/NetRx.Store.Monitor.Extension/Properties/AssemblyInfo.cs +++ b/src/NetRx.Store.Monitor.Extension/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] diff --git a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj index a93e52c..8b0db06 100644 --- a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj +++ b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj @@ -6,7 +6,7 @@ Key.snk NetRx.Store.Monitor.Shared - 2.0.0 + 2.1.0 Vitalii Ilchenko Includes library which allows to attach NetRx.Store Monitor tool to an application at a runtime https://github.com/ilchenkob/NetRx.Store diff --git a/src/NetRx.Store/NetRx.Store.csproj b/src/NetRx.Store/NetRx.Store.csproj index b05a364..034d7b7 100644 --- a/src/NetRx.Store/NetRx.Store.csproj +++ b/src/NetRx.Store/NetRx.Store.csproj @@ -4,7 +4,7 @@ netstandard2.1 NetRx NetRx.Store - 2.0.0 + 2.1.0 Vitalii Ilchenko State management for .Net projects, inspired by @ngrx/store https://github.com/ilchenkob/NetRx.Store @@ -17,6 +17,7 @@ MIT + 2.1.0.0 From a531181f3f044e2f5b064cb05287f860687f1102 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 22 Nov 2020 23:37:29 +0000 Subject: [PATCH 3/5] Update to Fix build and not navigate down properties. --- .../NetRx.Store.Monitor.Extension.csproj | 2 +- src/NetRx.Store.Monitor.Extension/app.config | 2 +- .../NetRx.Store.Monitor.Shared.csproj | 2 +- src/NetRx.Store.Tests/Store/StoreTest.cs | 7 ++----- src/NetRx.Store/NetRx.Store.csproj | 2 +- src/NetRx.Store/Store/StateWrapper.cs | 5 ----- 6 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj b/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj index 94fbea6..85f91a5 100644 --- a/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj +++ b/src/NetRx.Store.Monitor.Extension/NetRx.Store.Monitor.Extension.csproj @@ -26,7 +26,7 @@ Properties NetRx.Store.Monitor.Extension NetRx.Store.Monitor.Extension - v4.8 + v4.7 true true true diff --git a/src/NetRx.Store.Monitor.Extension/app.config b/src/NetRx.Store.Monitor.Extension/app.config index c764f53..ac92545 100644 --- a/src/NetRx.Store.Monitor.Extension/app.config +++ b/src/NetRx.Store.Monitor.Extension/app.config @@ -8,4 +8,4 @@ - + diff --git a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj index 8b0db06..840cdb6 100644 --- a/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj +++ b/src/NetRx.Store.Monitor.Shared/NetRx.Store.Monitor.Shared.csproj @@ -1,7 +1,7 @@ - netstandard2.1 + netstandard2.0 true Key.snk diff --git a/src/NetRx.Store.Tests/Store/StoreTest.cs b/src/NetRx.Store.Tests/Store/StoreTest.cs index 9340776..d64d4ae 100644 --- a/src/NetRx.Store.Tests/Store/StoreTest.cs +++ b/src/NetRx.Store.Tests/Store/StoreTest.cs @@ -159,16 +159,13 @@ public void Dispatch_Should_call_Reducer_Reduce_and_observable_should_invoke() var disposable = store.Select(f=> f.ReferenceObect) .Subscribe(f => selectedObect = f); - + store.Dispatch(new SetReferenceObjectAction(newObject)); disposable.Dispose(); Assert.Same(newObject, selectedObect); - - + } - - } } diff --git a/src/NetRx.Store/NetRx.Store.csproj b/src/NetRx.Store/NetRx.Store.csproj index 034d7b7..4047083 100644 --- a/src/NetRx.Store/NetRx.Store.csproj +++ b/src/NetRx.Store/NetRx.Store.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + netstandard2.0 NetRx NetRx.Store 2.1.0 diff --git a/src/NetRx.Store/Store/StateWrapper.cs b/src/NetRx.Store/Store/StateWrapper.cs index 4cd4605..8119a5b 100644 --- a/src/NetRx.Store/Store/StateWrapper.cs +++ b/src/NetRx.Store/Store/StateWrapper.cs @@ -93,11 +93,6 @@ private void BuildGetters(Type type, string prefix) _gettersCache[OriginalTypeName].Add(name, getExpression.Compile()); - if (!p.PropertyType.FullName.StartsWith("System.", StringComparison.InvariantCulture) - && !isEnumerable) - { - BuildGetters(p.PropertyType, name); - } } } From 06bbd36d1a12310a7976b51cd448137961c2ba3a Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 22 Nov 2020 23:43:54 +0000 Subject: [PATCH 4/5] Revert Test Project to netcore 3.1 --- src/NetRx.Store.Tests/NetRx.Store.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj index 1a70471..dd13f3f 100644 --- a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj +++ b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 From 2fb2c00b230fcd90a1e603676dc9bce6df9db07b Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 22 Nov 2020 23:45:27 +0000 Subject: [PATCH 5/5] Revert to .netcore 2.2 --- src/NetRx.Store.Tests/NetRx.Store.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj index dd13f3f..5b1cff3 100644 --- a/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj +++ b/src/NetRx.Store.Tests/NetRx.Store.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + netcoreapp2.2