diff --git a/TrackerDog.NuGet.Signed/TrackerDog.NuGet.Signed.nuproj b/TrackerDog.NuGet.Signed/TrackerDog.NuGet.Signed.nuproj index c991729..9bf0520 100644 --- a/TrackerDog.NuGet.Signed/TrackerDog.NuGet.Signed.nuproj +++ b/TrackerDog.NuGet.Signed/TrackerDog.NuGet.Signed.nuproj @@ -20,7 +20,7 @@ TrackerDog.Signed - 2.1.3 + 2.1.4 TrackerDog: A generic .NET object change tracker (SIGNED) Matías Fidemraizer Matías Fidemraizer diff --git a/TrackerDog.NuGet/TrackerDog.NuGet.nuproj b/TrackerDog.NuGet/TrackerDog.NuGet.nuproj index 1ac36cb..1f3cf7b 100644 --- a/TrackerDog.NuGet/TrackerDog.NuGet.nuproj +++ b/TrackerDog.NuGet/TrackerDog.NuGet.nuproj @@ -20,13 +20,13 @@ TrackerDog - 2.1.3 + 2.1.4 TrackerDog: A generic .NET object change tracker Matías Fidemraizer Matías Fidemraizer Track changes of any .NET object and full object graphs TrackerDog turns any .NET object or full object graph into a change-trackable object - See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.3 + See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.4 http://matiasfidemrazer.com/trackerdog/ https://github.com/mfidemraizer/trackerdog/blob/master/LICENSE Copyright © Matías Fidemraizer diff --git a/TrackerDog.Signed/Properties/AssemblyInfo.cs b/TrackerDog.Signed/Properties/AssemblyInfo.cs index 9aa7d1f..91fd590 100644 --- a/TrackerDog.Signed/Properties/AssemblyInfo.cs +++ b/TrackerDog.Signed/Properties/AssemblyInfo.cs @@ -33,8 +33,8 @@ // 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("2.0.1.0")] -[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.1.4.0")] +[assembly: AssemblyFileVersion("2.1.4.0")] [assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)] [assembly: InternalsVisibleTo("TrackerDog.Test.Signed, PublicKey=00240000048000009400000006020000002400005253413100040000010001001ffcf2febdbe56c43afff66e091d7220aa0e53b1638c84e8ae732b444410137f0cc754459f5691f74313921820a490e8761982edac1f051ba141be96bb9f82b4ea4a80b6b87e8c99831fdb69473821dbda3622a8cd3c439ddf3b76cba5ff89809423b7e02ea2b55a12f2b2f5ce0ce377bb2bb4831ce02f7a71cce368e346ecba")] \ No newline at end of file diff --git a/TrackerDog.Signed/TrackerDog.Signed.csproj b/TrackerDog.Signed/TrackerDog.Signed.csproj index cfdf980..77c80c6 100644 --- a/TrackerDog.Signed/TrackerDog.Signed.csproj +++ b/TrackerDog.Signed/TrackerDog.Signed.csproj @@ -43,10 +43,6 @@ ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True - - ..\packages\FastMember.1.1.0\lib\net40\FastMember.dll - True - ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll True @@ -72,6 +68,9 @@ ChangeTrackableObjectState.cs + + CollectionChangeTrackingContext.cs + CollectionHandling\CollectionChange.cs diff --git a/TrackerDog.Signed/packages.config b/TrackerDog.Signed/packages.config index 680fc2d..37cb461 100644 --- a/TrackerDog.Signed/packages.config +++ b/TrackerDog.Signed/packages.config @@ -1,7 +1,6 @@  - diff --git a/TrackerDog.Test.Signed/TrackerDog.Test.Signed.csproj b/TrackerDog.Test.Signed/TrackerDog.Test.Signed.csproj index 029cf6d..38e19e4 100644 --- a/TrackerDog.Test.Signed/TrackerDog.Test.Signed.csproj +++ b/TrackerDog.Test.Signed/TrackerDog.Test.Signed.csproj @@ -44,6 +44,10 @@ TrackerDog.Test.snk + + ..\packages\AutoMapper.5.2.0\lib\net45\AutoMapper.dll + True + ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True diff --git a/TrackerDog.Test/ObjectContainer.cs b/TrackerDog.Test/ObjectContainer.cs new file mode 100644 index 0000000..7c2e751 --- /dev/null +++ b/TrackerDog.Test/ObjectContainer.cs @@ -0,0 +1,6 @@ +namespace TrackerDog.Test +{ + public class ObjectContainer + { + } +} \ No newline at end of file diff --git a/TrackerDog.Test/TrackerDog.Test.csproj b/TrackerDog.Test/TrackerDog.Test.csproj index d346e6d..9e95f36 100644 --- a/TrackerDog.Test/TrackerDog.Test.csproj +++ b/TrackerDog.Test/TrackerDog.Test.csproj @@ -81,12 +81,16 @@ 4 + + ..\packages\AutoMapper.5.2.0\lib\net45\AutoMapper.dll + True + ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True - - ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll + + ..\packages\FastMember.1.1.0\lib\net40\FastMember.dll True @@ -118,6 +122,7 @@ + diff --git a/TrackerDog.Test/packages.config b/TrackerDog.Test/packages.config index b9d2bca..52396a7 100644 --- a/TrackerDog.Test/packages.config +++ b/TrackerDog.Test/packages.config @@ -1,7 +1,7 @@  - + diff --git a/TrackerDog/CollectionChangeTrackingContext.cs b/TrackerDog/CollectionChangeTrackingContext.cs new file mode 100644 index 0000000..a956d26 --- /dev/null +++ b/TrackerDog/CollectionChangeTrackingContext.cs @@ -0,0 +1,12 @@ +using TrackerDog.Configuration; + +namespace TrackerDog +{ + internal sealed class CollectionChangeTrackingContext + { + /// + /// Gets associated change-tracking configuration + /// + public IObjectChangeTrackingConfiguration Configuration { get; set; } + } +} \ No newline at end of file diff --git a/TrackerDog/IChangeTrackableCollection.cs b/TrackerDog/IChangeTrackableCollection.cs index a16e236..61d5868 100644 --- a/TrackerDog/IChangeTrackableCollection.cs +++ b/TrackerDog/IChangeTrackableCollection.cs @@ -20,6 +20,8 @@ internal interface IChangeTrackableCollection : INotifyCollectionChanged, IHasPa /// HashSet RemovedItems { get; } + CollectionChangeTrackingContext GetChangeTrackingContext(); + /// /// Raises the collection changed event to let a change tracker be aware that the collection has changed. /// diff --git a/TrackerDog/IChangeTrackableCollectionContract.cs b/TrackerDog/IChangeTrackableCollectionContract.cs index 7f2f58f..0977a34 100644 --- a/TrackerDog/IChangeTrackableCollectionContract.cs +++ b/TrackerDog/IChangeTrackableCollectionContract.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics.Contracts; using System.Linq; @@ -19,6 +20,13 @@ internal abstract class IChangeTrackableCollectionContract : IChangeTrackableCol public event NotifyCollectionChangedEventHandler CollectionChanged; + public CollectionChangeTrackingContext GetChangeTrackingContext() + { + Contract.Ensures(Contract.Result() != null); + + throw new NotImplementedException(); + } + public void RaiseCollectionChanged(NotifyCollectionChangedAction action, IEnumerable changedItems) { Contract.Requires(changedItems != null && changedItems.Count() > 0, "A collection change must change some item"); diff --git a/TrackerDog/Mixins/ChangeTrackableCollectionMixin.cs b/TrackerDog/Mixins/ChangeTrackableCollectionMixin.cs index 0f18d00..0f97767 100644 --- a/TrackerDog/Mixins/ChangeTrackableCollectionMixin.cs +++ b/TrackerDog/Mixins/ChangeTrackableCollectionMixin.cs @@ -8,6 +8,7 @@ namespace TrackerDog.Mixins { internal class ChangeTrackableCollectionMixin : IChangeTrackableCollection, IReadOnlyChangeTrackableCollection { + private readonly static Guid _id = Guid.NewGuid(); private readonly HashSet _addedItems = new HashSet(); private readonly HashSet _removedItems = new HashSet(); @@ -15,6 +16,7 @@ internal class ChangeTrackableCollectionMixin : IChangeTrackableCollection, IRea public event NotifyCollectionChangedEventHandler CollectionChanged; internal Guid Id => _id; + private CollectionChangeTrackingContext ChangeTrackingContext { get; } = new CollectionChangeTrackingContext(); public IChangeTrackableObject ParentObject { get; set; } public PropertyInfo ParentObjectProperty { get; set; } public IImmutableSet AddedItems => _addedItems.ToImmutableHashSet(); @@ -22,14 +24,15 @@ internal class ChangeTrackableCollectionMixin : IChangeTrackableCollection, IRea HashSet IChangeTrackableCollection.AddedItems => _addedItems; HashSet IChangeTrackableCollection.RemovedItems => _removedItems; + public CollectionChangeTrackingContext GetChangeTrackingContext() => ChangeTrackingContext; + public void RaiseCollectionChanged(NotifyCollectionChangedAction action, IEnumerable changedItems) { - if (CollectionChanged != null) - CollectionChanged - ( - this, - new NotifyCollectionChangedEventArgs(action, changedItems.ToImmutableList()) - ); + CollectionChanged?.Invoke + ( + this, + new NotifyCollectionChangedEventArgs(action, changedItems.ToImmutableList()) + ); } public override bool Equals(object obj) diff --git a/TrackerDog/ObjectChangeTrackingExtensions.cs b/TrackerDog/ObjectChangeTrackingExtensions.cs index 5ad650f..f234962 100644 --- a/TrackerDog/ObjectChangeTrackingExtensions.cs +++ b/TrackerDog/ObjectChangeTrackingExtensions.cs @@ -253,10 +253,8 @@ public static IEnumerable ToUntrackedEnumerable(this IEnumerable enumerable, Typ else collectionTypeArguments.Add(enumerable.GetCollectionItemType()); - IEnumerator collectionEnumerator = enumerable.GetEnumerator(); - collectionEnumerator.MoveNext(); + IObjectChangeTrackingConfiguration configuration = ((IChangeTrackableCollection)enumerable).GetChangeTrackingContext().Configuration; - IObjectChangeTrackingConfiguration configuration = ((IChangeTrackableObject)collectionEnumerator.Current).GetChangeTrackingContext().Configuration; IEnumerable enumerableCopy = (IEnumerable)configuration.Collections.GetImplementation(targetCollectionType) .Value.Type.CreateInstanceWithGenericArgs(null, collectionTypeArguments.ToArray()); @@ -298,11 +296,6 @@ internal static object ToUntypedUntracked(this object some) IProxyTargetAccessor proxyTargetAccessor = (IProxyTargetAccessor)trackable; object target = proxyTargetAccessor.DynProxyGetTarget(); - JsonSerializerSettings serializerSettings = new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Serialize - }; - object unwrapped = target.CloneIt(some.GetType().GetActualTypeIfTrackable()); ObjectChangeTracker changeTracker = (ObjectChangeTracker)trackable.GetChangeTracker(); diff --git a/TrackerDog/ObjectExtensions.cs b/TrackerDog/ObjectExtensions.cs index 147108a..a9c48c8 100644 --- a/TrackerDog/ObjectExtensions.cs +++ b/TrackerDog/ObjectExtensions.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; -using System.Dynamic; using TrackerDog.Serialization.Json; namespace TrackerDog @@ -9,18 +9,11 @@ internal static class ObjectExtensions { public static object CloneIt(this object some, Type type) { - JsonSerializerSettings serializerSettings = new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - ContractResolver = new DynamicObjectContractResolver() - }; + JsonSerializer serializer = new JsonSerializer(); + serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + serializer.ContractResolver = new DynamicObjectContractResolver(); - if (some is IDynamicMetaObjectProvider) - serializerSettings.Converters.Add(new DynamicObjectWithDeclaredPropertiesConverter()); - - string json = JsonConvert.SerializeObject(some, serializerSettings); - - return JsonConvert.DeserializeObject(json, type, serializerSettings); + return JObject.FromObject(some, serializer).ToObject(type, serializer); } } } \ No newline at end of file diff --git a/TrackerDog/Properties/AssemblyInfo.cs b/TrackerDog/Properties/AssemblyInfo.cs index 2c7eb7e..1c98dd2 100644 --- a/TrackerDog/Properties/AssemblyInfo.cs +++ b/TrackerDog/Properties/AssemblyInfo.cs @@ -32,7 +32,7 @@ // 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("2.0.1.0")] -[assembly: AssemblyFileVersion("2.0.1.0")] +[assembly: AssemblyVersion("2.1.4.0")] +[assembly: AssemblyFileVersion("2.1.4.0")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("TrackerDog.Test")] \ No newline at end of file diff --git a/TrackerDog/Serialization/Json/DynamicObjectContractResolver.cs b/TrackerDog/Serialization/Json/DynamicObjectContractResolver.cs index d09793d..1a52455 100644 --- a/TrackerDog/Serialization/Json/DynamicObjectContractResolver.cs +++ b/TrackerDog/Serialization/Json/DynamicObjectContractResolver.cs @@ -1,6 +1,10 @@ -using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using System; +using System.Collections.Generic; using System.Dynamic; +using System.Linq; +using System.Reflection; namespace TrackerDog.Serialization.Json { @@ -15,6 +19,5 @@ protected override JsonContract CreateContract(Type objectType) return base.CreateContract(objectType); } - } } \ No newline at end of file diff --git a/TrackerDog/Serialization/Json/DynamicObjectWithDeclaredPropertiesConverter.cs b/TrackerDog/Serialization/Json/DynamicObjectWithDeclaredPropertiesConverter.cs index e80c81a..3629ee8 100644 --- a/TrackerDog/Serialization/Json/DynamicObjectWithDeclaredPropertiesConverter.cs +++ b/TrackerDog/Serialization/Json/DynamicObjectWithDeclaredPropertiesConverter.cs @@ -45,7 +45,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s && !Attribute.IsDefined(p, typeof(JsonIgnoreAttribute)) ).ToList(); - JObject o = (JObject)JToken.FromObject(value); + JObject o = (JObject)JToken.FromObject(value, serializer); foreach (PropertyInfo property in properties) if (o[property.Name] == null) diff --git a/TrackerDog/TrackableObjectFactoryInternal.cs b/TrackerDog/TrackableObjectFactoryInternal.cs index 0cc3c38..0f58848 100644 --- a/TrackerDog/TrackableObjectFactoryInternal.cs +++ b/TrackerDog/TrackableObjectFactoryInternal.cs @@ -161,7 +161,9 @@ public object CreateForCollection(object some, IChangeTrackableObject parentObje bool canTrackCollectionType = Configuration.CanTrackType(genericCollectionType); ProxyGenerationOptions options = new ProxyGenerationOptions(new CollectionterceptionHook()); - options.AddMixinInstance(new ChangeTrackableCollectionMixin()); + ChangeTrackableCollectionMixin changeTrackingMixin = new ChangeTrackableCollectionMixin(); + changeTrackingMixin.GetChangeTrackingContext().Configuration = Configuration; + options.AddMixinInstance(changeTrackingMixin); KeyValuePair collectionImplementationDetail = Configuration.Collections.GetImplementation(parentObjectProperty.PropertyType); diff --git a/TrackerDog/TrackerDog.csproj b/TrackerDog/TrackerDog.csproj index 3f75264..1ca9ef3 100644 --- a/TrackerDog/TrackerDog.csproj +++ b/TrackerDog/TrackerDog.csproj @@ -81,12 +81,16 @@ false + + ..\packages\AutoMapper.5.2.0\lib\net45\AutoMapper.dll + True + ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll True - - ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll + + ..\packages\FastMember.1.1.0\lib\net40\FastMember.dll True @@ -108,6 +112,7 @@ + diff --git a/TrackerDog/packages.config b/TrackerDog/packages.config index 7ecc0fb..ef40584 100644 --- a/TrackerDog/packages.config +++ b/TrackerDog/packages.config @@ -1,7 +1,7 @@  - +