Skip to content

Commit

Permalink
Solves issue #23
Browse files Browse the repository at this point in the history
  • Loading branch information
mfidemraizer committed Dec 8, 2016
1 parent bdec00f commit c9502ed
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 53 deletions.
4 changes: 2 additions & 2 deletions TrackerDog.NuGet.Signed/TrackerDog.NuGet.Signed.nuproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 20,13 @@
<Import Project="$(NuProjPath)\NuProj.props" Condition="Exists('$(NuProjPath)\NuProj.props')" />
<PropertyGroup Label="Configuration">
<Id>TrackerDog.Signed</Id>
<Version>2.1.2</Version>
<Version>2.1.3</Version>
<Title>TrackerDog: A generic .NET object change tracker (SIGNED)</Title>
<Authors>Matías Fidemraizer</Authors>
<Owners>Matías Fidemraizer</Owners>
<Summary>Track changes of any .NET object and full object graphs</Summary>
<Description>TrackerDog turns any .NET object or full object graph into a change-trackable object</Description>
<ReleaseNotes>See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.2</ReleaseNotes>
<ReleaseNotes>See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.3</ReleaseNotes>
<ProjectUrl>http://matiasfidemrazer.com/trackerdog/</ProjectUrl>
<LicenseUrl>https://github.com/mfidemraizer/trackerdog/blob/master/LICENSE</LicenseUrl>
<Copyright>Copyright © Matías Fidemraizer</Copyright>
Expand Down
4 changes: 2 additions & 2 deletions TrackerDog.NuGet/TrackerDog.NuGet.nuproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 20,13 @@
<Import Project="$(NuProjPath)\NuProj.props" Condition="Exists('$(NuProjPath)\NuProj.props')" />
<PropertyGroup Label="Configuration">
<Id>TrackerDog</Id>
<Version>2.1.2</Version>
<Version>2.1.3</Version>
<Title>TrackerDog: A generic .NET object change tracker</Title>
<Authors>Matías Fidemraizer</Authors>
<Owners>Matías Fidemraizer</Owners>
<Summary>Track changes of any .NET object and full object graphs</Summary>
<Description>TrackerDog turns any .NET object or full object graph into a change-trackable object</Description>
<ReleaseNotes>See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.2</ReleaseNotes>
<ReleaseNotes>See release notes here: https://github.com/mfidemraizer/trackerdog/releases/tag/v2.1.3</ReleaseNotes>
<ProjectUrl>http://matiasfidemrazer.com/trackerdog/</ProjectUrl>
<LicenseUrl>https://github.com/mfidemraizer/trackerdog/blob/master/LICENSE</LicenseUrl>
<Copyright>Copyright © Matías Fidemraizer</Copyright>
Expand Down
18 changes: 14 additions & 4 deletions TrackerDog.Signed/TrackerDog.Signed.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 43,21 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FastMember, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9056fda458ff61cf, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.0.0.11\lib\net40\FastMember.dll</HintPath>
<Reference Include="FastMember, Version=1.0.0.9, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.1.1.0\lib\net40\FastMember.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FastMember.Signed, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9e8f22703bef9a29, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Reference Include="System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.3.0\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Core" />
Expand Down Expand Up @@ -248,6 252,9 @@
<Compile Include="..\TrackerDog\ObjectChangeTrackingExtensions.cs">
<Link>ObjectChangeTrackingExtensions.cs</Link>
</Compile>
<Compile Include="..\TrackerDog\ObjectExtensions.cs">
<Link>ObjectExtensions.cs</Link>
</Compile>
<Compile Include="..\TrackerDog\ObjectGraphTrackingInfo.cs">
<Link>ObjectGraphTrackingInfo.cs</Link>
</Compile>
Expand All @@ -266,6 273,9 @@
<Compile Include="..\TrackerDog\ReflectionExtensions.cs">
<Link>ReflectionExtensions.cs</Link>
</Compile>
<Compile Include="..\TrackerDog\Serialization\Json\DynamicObjectContractResolver.cs">
<Link>Serialization\Json\DynamicObjectContractResolver.cs</Link>
</Compile>
<Compile Include="..\TrackerDog\Serialization\Json\DynamicObjectWithDeclaredPropertiesConverter.cs">
<Link>Serialization\Json\DynamicObjectWithDeclaredPropertiesConverter.cs</Link>
</Compile>
Expand Down
6 changes: 3 additions & 3 deletions TrackerDog.Signed/packages.config
Original file line number Diff line number Diff line change
@@ -1,10 1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net452" />
<package id="FastMember" version="1.0.0.11" targetFramework="net452" />
<package id="FastMember.Signed" version="1.0.0.11" targetFramework="net45" />
<package id="FastMember" version="1.1.0" targetFramework="net45" />
<package id="FastMember.Signed" version="1.1.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="NuProj" version="0.11.14-beta" targetFramework="net45" developmentDependency="true" />
<package id="NuProj.Common" version="0.11.14-beta" targetFramework="net45" developmentDependency="true" />
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net452" />
<package id="System.Collections.Immutable" version="1.3.0" targetFramework="net45" />
</packages>
13 changes: 9 additions & 4 deletions TrackerDog.Test.Signed/TrackerDog.Test.Signed.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 48,12 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FastMember, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9056fda458ff61cf, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.0.0.11\lib\net40\FastMember.dll</HintPath>
<Reference Include="FastMember, Version=1.0.0.9, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.1.1.0\lib\net40\FastMember.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FastMember.Signed, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9e8f22703bef9a29, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
Expand All @@ -58,10 62,11 @@
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Reference Include="System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.3.0\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
Expand Down
6 changes: 3 additions & 3 deletions TrackerDog.Test.Signed/packages.config
Original file line number Diff line number Diff line change
@@ -1,10 1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net452" />
<package id="FastMember" version="1.0.0.11" targetFramework="net452" />
<package id="FastMember.Signed" version="1.0.0.11" targetFramework="net45" />
<package id="FastMember" version="1.1.0" targetFramework="net45" />
<package id="FastMember.Signed" version="1.1.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="NuProj" version="0.11.14-beta" targetFramework="net45" developmentDependency="true" />
<package id="NuProj.Common" version="0.11.14-beta" targetFramework="net45" developmentDependency="true" />
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net452" />
<package id="System.Collections.Immutable" version="1.3.0" targetFramework="net45" />
</packages>
9 changes: 5 additions & 4 deletions TrackerDog.Test/TrackerDog.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 85,8 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FastMember, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9056fda458ff61cf, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.0.0.11\lib\net40\FastMember.dll</HintPath>
<Reference Include="FastMember.Signed, Version=1.0.0.9, Culture=neutral, PublicKeyToken=9e8f22703bef9a29, processorArchitecture=MSIL">
<HintPath>..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
Expand All @@ -95,10 95,11 @@
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Reference Include="System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.3.0\lib\portable-net45 win8 wp8 wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
Expand Down
4 changes: 2 additions & 2 deletions TrackerDog.Test/packages.config
Original file line number Diff line number Diff line change
@@ -1,8 1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net452" />
<package id="FastMember.Signed" version="1.0.0.11" targetFramework="net452" />
<package id="FastMember.Signed" version="1.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="NuProj.Common" version="0.11.14-beta" targetFramework="net452" developmentDependency="true" />
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net452" />
<package id="System.Collections.Immutable" version="1.3.0" targetFramework="net452" />
</packages>
37 changes: 23 additions & 14 deletions TrackerDog/ObjectChangeTrackingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 271,7 @@ public static IEnumerable ToUntrackedEnumerable(this IEnumerable enumerable, Typ

foreach (object item in enumerable)
{
addMethod.Invoke(enumerableCopy, new[] { item.ToUntracked() });
addMethod.Invoke(enumerableCopy, new[] { item.ToUntypedUntracked() });
}

return enumerableCopy;
Expand All @@ -282,13 282,11 @@ public static IEnumerable ToUntrackedEnumerable(this IEnumerable enumerable, Typ
/// <summary>
/// Turns given object and all associates to untrackable objects (i.e. POCO objects).
/// </summary>
/// <typeparam name="TObject">The type of the whole object to untrack</typeparam>
/// <param name="some">The whole object to untrack</param>
/// <returns>The untracked version of given object</returns>
public static TObject ToUntracked<TObject>(this TObject some)
where TObject : class
internal static object ToUntypedUntracked(this object some)
{
Contract.Ensures(!(Contract.Result<TObject>() is IProxyTargetAccessor), "To convert a tracked object to untracked one the whole tracked object must be created from a pre-existing object");
Contract.Ensures(!(Contract.Result<object>() is IProxyTargetAccessor), "To convert a tracked object to untracked one the whole tracked object must be created from a pre-existing object");

if (some == null)
return some;
Expand All @@ -298,17 296,14 @@ public static TObject ToUntracked<TObject>(this TObject some)
if (trackable != null)
{
IProxyTargetAccessor proxyTargetAccessor = (IProxyTargetAccessor)trackable;
TObject target = (TObject)proxyTargetAccessor.DynProxyGetTarget();

JsonSerializerSettings serializerSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
object target = proxyTargetAccessor.DynProxyGetTarget();

if (target is IDynamicMetaObjectProvider)
serializerSettings.Converters.Add(new DynamicObjectWithDeclaredPropertiesConverter());
JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};

TObject unwrapped = JsonConvert.DeserializeObject<TObject>
(
JsonConvert.SerializeObject(target, serializerSettings)
);
object unwrapped = target.CloneIt(some.GetType().GetActualTypeIfTrackable());

ObjectChangeTracker changeTracker = (ObjectChangeTracker)trackable.GetChangeTracker();

Expand Down Expand Up @@ -339,6 334,20 @@ public static TObject ToUntracked<TObject>(this TObject some)
else return some;
}

/// <summary>
/// Turns given object and all associates to untrackable objects (i.e. POCO objects).
/// </summary>
/// <typeparam name="TObject">The type of the whole object to untrack</typeparam>
/// <param name="some">The whole object to untrack</param>
/// <returns>The untracked version of given object</returns>
public static TObject ToUntracked<TObject>(this TObject some)
where TObject : class
{
Contract.Ensures(!(Contract.Result<TObject>() is IProxyTargetAccessor), "To convert a tracked object to untracked one the whole tracked object must be created from a pre-existing object");

return (TObject)some.ToUntypedUntracked();
}

/// <summary>
/// Gets the value of given selected property that had when the change-tracked object started to track its changes.
/// </summary>
Expand Down
26 changes: 26 additions & 0 deletions TrackerDog/ObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,26 @@
using Newtonsoft.Json;
using System;
using System.Dynamic;
using TrackerDog.Serialization.Json;

namespace TrackerDog
{
internal static class ObjectExtensions
{
public static object CloneIt(this object some, Type type)
{
JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new DynamicObjectContractResolver()
};

if (some is IDynamicMetaObjectProvider)
serializerSettings.Converters.Add(new DynamicObjectWithDeclaredPropertiesConverter());

string json = JsonConvert.SerializeObject(some, serializerSettings);

return JsonConvert.DeserializeObject(json, type, serializerSettings);
}
}
}
20 changes: 20 additions & 0 deletions TrackerDog/Serialization/Json/DynamicObjectContractResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,20 @@
using Newtonsoft.Json.Serialization;
using System;
using System.Dynamic;

namespace TrackerDog.Serialization.Json
{
internal class DynamicObjectContractResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(objectType))
{
return CreateObjectContract(objectType);
}

return base.CreateContract(objectType);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 3,15 @@
using System;
using System.Dynamic;
using System.Linq;
using System.Reflection;

namespace TrackerDog.Serialization.Json
{
internal sealed class DynamicObjectWithDeclaredPropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
return typeof(IDynamicMetaObjectProvider).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
Expand All @@ -21,27 22,34 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
JObject jObject = JObject.Load(reader);

var target = Activator.CreateInstance(objectType);

JsonReader jObjectReader = jObject.CreateReader();
jObjectReader.Culture = reader.Culture;
jObjectReader.DateParseHandling = reader.DateParseHandling;
jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
jObjectReader.FloatParseHandling = reader.FloatParseHandling;

serializer.Populate(jObjectReader, target);

return target;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var properties = value.GetType().GetProperties().Where(x => x.PropertyType != typeof(DynamicObject)).ToList();
JObject o = (JObject)JToken.FromObject(value);
var properties = value.GetType()
.GetProperties()
.Where
(
p => p.PropertyType != typeof(DynamicObject)
&& p.GetIndexParameters().Length == 0
&& !Attribute.IsDefined(p, typeof(JsonIgnoreAttribute))
).ToList();

properties.ForEach(x =>
{
o.AddFirst(new JProperty(x.Name, x.GetValue(value)));
});
JObject o = (JObject)JToken.FromObject(value);

foreach (PropertyInfo property in properties)
if (o[property.Name] == null)
o.AddFirst(new JProperty(property.Name, property.GetValue(value)));

o.WriteTo(writer);
}
Expand Down
Loading

0 comments on commit c9502ed

Please sign in to comment.