diff --git a/Aspects/Diagnostics/ClassMetadataRegistrar.cs b/Aspects/Diagnostics/ClassMetadataRegistrar.cs
index 720ea8b..475d9a4 100644
--- a/Aspects/Diagnostics/ClassMetadataRegistrar.cs
+++ b/Aspects/Diagnostics/ClassMetadataRegistrar.cs
@@ -1,5 +1,4 @@
using System;
-using System.Configuration;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
//using System.Data;
@@ -55,24 +54,31 @@ public static ClassMetadataRegistrar RegisterMetadata()
}
///
- /// Registers the dump metadata and instance related to the specified type.
+ /// Registers the dump metadata and instance related to the specified type.
///
/// The type for which the metadata is being registered.
/// The dump metadata type.
/// The dump attribute.
+ ///
+ /// If set to and there is already dump metadata associated with the
+ /// the method will throw exception of type ;
+ /// otherwise it will silently override the existing metadata with and .
+ ///
/// The current instance of ClassMetadataRegistrar.
- ///
- /// Thrown if is .
+ /// Thrown if is .
+ ///
+ /// Thrown if is and there is already metadata associated with the .
///
public ClassMetadataRegistrar Register(
Type type,
Type metadataType,
- DumpAttribute dumpAttribute = null)
+ DumpAttribute dumpAttribute = null,
+ bool replace = false)
{
Contract.Requires(type != null, "type");
Contract.Ensures(Contract.Result() != null);
- ClassMetadataResolver.SetClassDumpData(type, metadataType, dumpAttribute);
+ ClassMetadataResolver.SetClassDumpData(type, metadataType, dumpAttribute, replace);
return this;
}
@@ -82,14 +88,23 @@ public ClassMetadataRegistrar Register(
/// The type for which the metadata is being registered.
/// The dump metadata type.
/// The dump attribute.
+ ///
+ /// If set to and there is already dump metadata associated with the
+ /// the method will throw exception of type ;
+ /// otherwise it will silently override the existing metadata with and the .
+ ///
/// The current instance of ClassMetadataRegistrar.
+ ///
+ /// Thrown if is and there is already metadata associated with the .
+ ///
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public ClassMetadataRegistrar Register(
- DumpAttribute dumpAttribute = null)
+ DumpAttribute dumpAttribute = null,
+ bool replace = false)
{
Contract.Ensures(Contract.Result() != null);
- return Register(typeof(T), typeof(TMetadata), dumpAttribute);
+ return Register(typeof(T), typeof(TMetadata), dumpAttribute, replace);
}
///
@@ -97,14 +112,23 @@ public ClassMetadataRegistrar Register(
///
/// The type for which the dump attribute is being registered.
/// The dump attribute.
+ ///
+ /// If set to and there is already dump metadata associated with the
+ /// the method will throw exception of type ;
+ /// otherwise it will silently override the existing metadata with itself - and the .
+ ///
/// The current instance of ClassMetadataRegistrar.
+ ///
+ /// Thrown if is and there is already metadata associated with the .
+ ///
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public ClassMetadataRegistrar Register(
- DumpAttribute dumpAttribute)
+ DumpAttribute dumpAttribute,
+ bool replace = false)
{
Contract.Ensures(Contract.Result() != null);
- return Register(typeof(T), null, dumpAttribute);
+ return Register(typeof(T), null, dumpAttribute, replace);
}
}
}
diff --git a/Aspects/Diagnostics/ClassMetadataResolver.cs b/Aspects/Diagnostics/ClassMetadataResolver.cs
index 318f2bb..c5ceb3b 100644
--- a/Aspects/Diagnostics/ClassMetadataResolver.cs
+++ b/Aspects/Diagnostics/ClassMetadataResolver.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.Contracts;
+using System.Globalization;
using System.Threading;
namespace vm.Aspects.Diagnostics
@@ -42,10 +42,19 @@ static Dictionary TypesDumpData
/// The type for which to set buddy type and dump attribute.
/// The metadata type (buddy class).
/// The dump attribute.
+ ///
+ /// If set to and there is already dump metadata associated with the
+ /// the method will throw exception of type ;
+ /// otherwise it will silently override the existing metadata with and .
+ ///
+ ///
+ /// Thrown if is and there is already metadata associated with the .
+ ///
public static void SetClassDumpData(
Type type,
Type metadata = null,
- DumpAttribute dumpAttribute = null)
+ DumpAttribute dumpAttribute = null,
+ bool replace = false)
{
Contract.Requires(type != null, "type");
@@ -58,7 +67,7 @@ public static void SetClassDumpData(
: type;
}
- AddClassDumpData(type, metadata, dumpAttribute);
+ AddClassDumpData(type, metadata, dumpAttribute, replace);
}
///
@@ -80,10 +89,17 @@ public static ClassDumpData GetClassDumpData(
// extract the dump data from the type
dumpData = ExtractClassDumpData(type);
- AddClassDumpData(type, dumpData.Value);
+ try
+ {
+ AddClassDumpData(type, dumpData.Value, false);
- // return what we found
- return dumpData.Value;
+ // return what we found
+ return dumpData.Value;
+ }
+ catch (InvalidOperationException)
+ {
+ return TryGetClassDumpData(type).Value;
+ }
}
static ClassDumpData ExtractClassDumpData(Type type)
@@ -121,20 +137,35 @@ static ClassDumpData ExtractClassDumpData(Type type)
return null;
}
- static void AddClassDumpData(Type type, Type buddy, DumpAttribute dumpAttribute)
+ static void AddClassDumpData(Type type, Type buddy, DumpAttribute dumpAttribute, bool replace)
{
Contract.Requires(type != null, nameof(type));
- AddClassDumpData(type, new ClassDumpData(buddy, dumpAttribute));
+ AddClassDumpData(type, new ClassDumpData(buddy, dumpAttribute), replace);
}
- static void AddClassDumpData(Type type, ClassDumpData classDumpData)
+ static void AddClassDumpData(Type type, ClassDumpData classDumpData, bool replace)
{
Contract.Requires(type != null, nameof(type));
+ TypesDumpDataSync.EnterWriteLock();
try
{
- TypesDumpDataSync.EnterWriteLock();
+ ClassDumpData dumpData;
+
+ if (!replace && TypesDumpData.TryGetValue(type, out dumpData))
+ {
+ if (dumpData == classDumpData)
+ return;
+
+ throw new InvalidOperationException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "The type {0} is already associated with metadata type {1} and a DumpAttribute instance.",
+ type.FullName,
+ TypesDumpData[type].Metadata.FullName));
+ }
+
TypesDumpData[type] = classDumpData;
}
finally
diff --git a/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec b/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec
index fce5d0c..439c12a 100644
--- a/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec
+++ b/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec
@@ -2,7 +2,7 @@
AspectObjectDumper
- 1.4.2
+ 1.5.0
Val Melamed
Val Melamed
@@ -28,7 +28,11 @@
* Build and tested with .NET 4.0, 4.6. This package targets .NET 4.0.
- Added the XML documentation.
+ ATTENTION: possible breaking change.
+ The methods registering metadata information - the overloaded family 'ClassMetadataRegistrar.Register' - were added a new parameter `bool replace = false`.
+ If the parameter is false (the default) and the method is invoked to replace existing mapping of a type to different pair of dump metadata type and `DumpAttribute` instance, it will throw `InvalidOperationException`.
+ This will allow to detect confusing dump behavior, when one registrar registers some metadata and another replaces it with different metadata. To preserve the old behavior or to allow overriding of dump behavior, set
+ the parameter 'replace = true'.
https://aspectobjectdumper.codeplex.com/license
https://aspectobjectdumper.codeplex.com/
diff --git a/Aspects/Diagnostics/Properties/AssemblyInfo.cs b/Aspects/Diagnostics/Properties/AssemblyInfo.cs
index 2a585b6..dd22233 100644
--- a/Aspects/Diagnostics/Properties/AssemblyInfo.cs
+++ b/Aspects/Diagnostics/Properties/AssemblyInfo.cs
@@ -2,9 +2,9 @@
[assembly: AssemblyTitle("vm.Aspects.Diagnostics.ObjectDumper")]
[assembly: AssemblyDescription("Dumps the properties' and fields' values of any .NET object in a text form.")]
-[assembly: AssemblyVersion("1.4.2")]
-[assembly: AssemblyFileVersion("1.4.2")]
-[assembly: AssemblyInformationalVersion("1.4.2")]
+[assembly: AssemblyVersion("1.5.0")]
+[assembly: AssemblyFileVersion("1.5.0")]
+[assembly: AssemblyInformationalVersion("1.5.0")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(
"vm.Aspects.Diagnostics.ObjectDumper.Tests, " +
diff --git a/Aspects/Diagnostics/Test/ObjectDumperTest/ClassMetadataCacheTest.cs b/Aspects/Diagnostics/Test/ObjectDumperTest/ClassMetadataCacheTest.cs
index 4ca17a8..3646a6e 100644
--- a/Aspects/Diagnostics/Test/ObjectDumperTest/ClassMetadataCacheTest.cs
+++ b/Aspects/Diagnostics/Test/ObjectDumperTest/ClassMetadataCacheTest.cs
@@ -21,7 +21,7 @@ static Dictionary TypesDumpData
[TestMethod]
public void TestSetClassDumpData_NullArg2n3()
{
- ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, null);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, null, true);
Assert.AreEqual(initialCacheSize+1, TypesDumpData.Count());
Assert.AreEqual(
@@ -32,7 +32,7 @@ public void TestSetClassDumpData_NullArg2n3()
[TestMethod]
public void TestSetClassDumpData_NullArg2()
{
- ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, new DumpAttribute(false));
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, new DumpAttribute(false), true);
Assert.AreEqual(initialCacheSize+1, TypesDumpData.Count());
Assert.AreEqual(
@@ -43,7 +43,7 @@ public void TestSetClassDumpData_NullArg2()
[TestMethod]
public void TestSetClassDumpData_NullArg3()
{
- ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), null);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), null, true);
Assert.AreEqual(initialCacheSize+1, TypesDumpData.Count());
Assert.AreEqual(
@@ -54,7 +54,7 @@ public void TestSetClassDumpData_NullArg3()
[TestMethod]
public void TestSetClassDumpData()
{
- ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), new DumpAttribute(false));
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), new DumpAttribute(false), true);
Assert.AreEqual(initialCacheSize+1, TypesDumpData.Count());
Assert.AreEqual(
@@ -62,6 +62,42 @@ public void TestSetClassDumpData()
TypesDumpData[typeof(ClassMetadataCacheTest)]);
}
+ //////////////////////////////////////////////////////////////////////////////
+
+ [TestMethod]
+ [ExpectedException(typeof(InvalidOperationException))]
+ public void TestSetClassDumpData_NullArg2n3_Exception()
+ {
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, null, true);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), null, false);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(InvalidOperationException))]
+ public void TestSetClassDumpData_NullArg2_Exception()
+ {
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, new DumpAttribute(false), true);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), null, new DumpAttribute(true), false);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(InvalidOperationException))]
+ public void TestSetClassDumpData_NullArg3_Exception()
+ {
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), null, true);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataCacheTest), null, false);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(InvalidOperationException))]
+ public void TestSetClassDumpData_Exception()
+ {
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataResolver), new DumpAttribute(false), true);
+ ClassMetadataResolver.SetClassDumpData(typeof(ClassMetadataCacheTest), typeof(ClassMetadataCacheTest), new DumpAttribute(true), false);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
[TestMethod]
public void TestGetClassDumpAttribute_InCache()
{
diff --git a/Aspects/NuGet/vm.Aspects.nuspec b/Aspects/NuGet/vm.Aspects.nuspec
index b64c3ec..47b9434 100644
--- a/Aspects/NuGet/vm.Aspects.nuspec
+++ b/Aspects/NuGet/vm.Aspects.nuspec
@@ -49,7 +49,7 @@ This will allow the inheritors to modify the behavior of the property Id, withou
version="6.1.3" />
+ version="1.5.0" />
diff --git a/Aspects/Test/Validation/ValidatorXmlStringTests.cs b/Aspects/Test/Validation/ValidatorXmlStringTests.cs
index 4ba4883..78d8fcd 100644
--- a/Aspects/Test/Validation/ValidatorXmlStringTests.cs
+++ b/Aspects/Test/Validation/ValidatorXmlStringTests.cs
@@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using vm.Aspects.Validation;
namespace vm.Aspects.Validation.Tests
{
@@ -7,9 +6,9 @@ namespace vm.Aspects.Validation.Tests
/// Summary description for ValidatorXmlStringTests
///
[TestClass]
- [DeploymentItem("..\\..\\Linq\\Expressions\\Serialization\\Tests\\Microsoft.Serialization.xsd")]
- [DeploymentItem("..\\..\\Linq\\Expressions\\Serialization\\Tests\\DataContract.xsd")]
- [DeploymentItem("..\\..\\Linq\\Expressions\\Serialization\\Documents\\Expression.xsd")]
+ [DeploymentItem("..\\..\\..\\Linq\\Expressions\\Serialization\\Tests\\Microsoft.Serialization.xsd")]
+ [DeploymentItem("..\\..\\..\\Linq\\Expressions\\Serialization\\Tests\\DataContract.xsd")]
+ [DeploymentItem("..\\..\\..\\Linq\\Expressions\\Serialization\\Documents\\Expression.xsd")]
public class ValidatorXmlStringTests
{
///