diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs
new file mode 100644
index 0000000000..c963fcffdd
--- /dev/null
+++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/AdapterFactory.cs
@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.JsonPatch.Internal;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.AspNetCore.JsonPatch.Adapters
+{
+ ///
+ /// The default AdapterFactory to be used for resolving .
+ ///
+ public class AdapterFactory : IAdapterFactory
+ {
+ ///
+ public virtual IAdapter Create(object target, IContractResolver contractResolver)
+ {
+ var jsonContract = contractResolver.ResolveContract(target.GetType());
+
+ if (target is IList)
+ {
+ return new ListAdapter();
+ }
+ else if (jsonContract is JsonDictionaryContract jsonDictionaryContract)
+ {
+ var type = typeof(DictionaryAdapter<,>).MakeGenericType(jsonDictionaryContract.DictionaryKeyType, jsonDictionaryContract.DictionaryValueType);
+ return (IAdapter)Activator.CreateInstance(type);
+ }
+ else if (jsonContract is JsonDynamicContract)
+ {
+ return new DynamicObjectAdapter();
+ }
+ else
+ {
+ return new PocoAdapter();
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs
new file mode 100644
index 0000000000..43ca1e65b6
--- /dev/null
+++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/IAdapterFactory.cs
@@ -0,0 +1,22 @@
+using Microsoft.AspNetCore.JsonPatch.Internal;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.AspNetCore.JsonPatch.Adapters
+{
+ ///
+ /// Defines the operations used for loading an based on the current object and ContractResolver.
+ ///
+ public interface IAdapterFactory
+ {
+ ///
+ /// Creates an for the current object
+ ///
+ /// The target object
+ /// The current contract resolver
+ /// The needed
+ IAdapter Create(object target, IContractResolver contractResolver);
+ }
+}
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs
index 73095b52c2..48d7e69b0f 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs
@@ -18,17 +18,37 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
/// The for logging .
public ObjectAdapter(
IContractResolver contractResolver,
- Action logErrorAction)
+ Action logErrorAction):
+ this(contractResolver, logErrorAction, new AdapterFactory())
{
- ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
- LogErrorAction = logErrorAction;
}
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The .
+ /// The for logging .
+ /// The to use when creating adaptors.
+ public ObjectAdapter(
+ IContractResolver contractResolver,
+ Action logErrorAction,
+ IAdapterFactory adapterFactory)
+ {
+ ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
+ LogErrorAction = logErrorAction;
+ AdapterFactory = adapterFactory ?? throw new ArgumentNullException(nameof(adapterFactory));
+ }
+
///
/// Gets or sets the .
///
public IContractResolver ContractResolver { get; }
+ ///
+ /// Gets or sets the
+ ///
+ public IAdapterFactory AdapterFactory { get; set; }
+
///
/// Action for logging .
///
@@ -75,7 +95,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
}
var parsedPath = new ParsedPath(path);
- var visitor = new ObjectVisitor(parsedPath, ContractResolver);
+ var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory);
var target = objectToApplyTo;
if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage))
@@ -144,7 +164,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
private void Remove(string path, object objectToApplyTo, Operation operationToReport)
{
var parsedPath = new ParsedPath(path);
- var visitor = new ObjectVisitor(parsedPath, ContractResolver);
+ var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory);
var target = objectToApplyTo;
if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage))
@@ -175,7 +195,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
}
var parsedPath = new ParsedPath(operation.path);
- var visitor = new ObjectVisitor(parsedPath, ContractResolver);
+ var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory);
var target = objectToApplyTo;
if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage))
@@ -239,7 +259,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
}
var parsedPath = new ParsedPath(operation.path);
- var visitor = new ObjectVisitor(parsedPath, ContractResolver);
+ var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory);
var target = objectToApplyTo;
if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage))
@@ -281,7 +301,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
propertyValue = null;
var parsedPath = new ParsedPath(fromLocation);
- var visitor = new ObjectVisitor(parsedPath, ContractResolver);
+ var visitor = new ObjectVisitor(parsedPath, ContractResolver, AdapterFactory);
var target = objectToGetValueFrom;
if (!visitor.TryVisit(ref target, out var adapter, out var errorMessage))
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs
index 8a344e24ee..be2bbffd86 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DictionaryAdapterOfTU.cs
@@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DictionaryAdapter : IAdapter
{
- public bool TryAdd(
+ public virtual bool TryAdd(
object target,
string segment,
IContractResolver contractResolver,
@@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryGet(
+ public virtual bool TryGet(
object target,
string segment,
IContractResolver contractResolver,
@@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryRemove(
+ public virtual bool TryRemove(
object target,
string segment,
IContractResolver contractResolver,
@@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryReplace(
+ public virtual bool TryReplace(
object target,
string segment,
IContractResolver contractResolver,
@@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryTest(
+ public virtual bool TryTest(
object target,
string segment,
IContractResolver contractResolver,
@@ -177,7 +177,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- public bool TryTraverse(
+ public virtual bool TryTraverse(
object target,
string segment,
IContractResolver contractResolver,
@@ -208,7 +208,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TryConvertKey(string key, out TKey convertedKey, out string errorMessage)
+ protected virtual bool TryConvertKey(string key, out TKey convertedKey, out string errorMessage)
{
var conversionResult = ConversionResultProvider.ConvertTo(key, typeof(TKey));
if (conversionResult.CanBeConverted)
@@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage)
+ protected virtual bool TryConvertValue(object value, out TValue convertedValue, out string errorMessage)
{
var conversionResult = ConversionResultProvider.ConvertTo(value, typeof(TValue));
if (conversionResult.CanBeConverted)
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs
index fb4adeb1f2..dc3c48266f 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/DynamicObjectAdapter.cs
@@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class DynamicObjectAdapter : IAdapter
{
- public bool TryAdd(
+ public virtual bool TryAdd(
object target,
string segment,
IContractResolver contractResolver,
@@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryGet(
+ public virtual bool TryGet(
object target,
string segment,
IContractResolver contractResolver,
@@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryRemove(
+ public virtual bool TryRemove(
object target,
string segment,
IContractResolver contractResolver,
@@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
- public bool TryReplace(
+ public virtual bool TryReplace(
object target,
string segment,
IContractResolver contractResolver,
@@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryTest(
+ public virtual bool TryTest(
object target,
string segment,
IContractResolver contractResolver,
@@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- public bool TryTraverse(
+ public virtual bool TryTraverse(
object target,
string segment,
IContractResolver contractResolver,
@@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TryGetDynamicObjectProperty(
+ protected virtual bool TryGetDynamicObjectProperty(
object target,
IContractResolver contractResolver,
string segment,
@@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TrySetDynamicObjectProperty(
+ protected virtual bool TrySetDynamicObjectProperty(
object target,
IContractResolver contractResolver,
string segment,
@@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TryConvertValue(object value, Type propertyType, out object convertedValue)
+ protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue)
{
var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType);
if (!conversionResult.CanBeConverted)
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs
index d1348fd5c6..597f7b9f5f 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ListAdapter.cs
@@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class ListAdapter : IAdapter
{
- public bool TryAdd(
+ public virtual bool TryAdd(
object target,
string segment,
IContractResolver contractResolver,
@@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryGet(
+ public virtual bool TryGet(
object target,
string segment,
IContractResolver contractResolver,
@@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryRemove(
+ public virtual bool TryRemove(
object target,
string segment,
IContractResolver contractResolver,
@@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryReplace(
+ public virtual bool TryReplace(
object target,
string segment,
IContractResolver contractResolver,
@@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryTest(
+ public virtual bool TryTest(
object target,
string segment,
IContractResolver contractResolver,
@@ -189,7 +189,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- public bool TryTraverse(
+ public virtual bool TryTraverse(
object target,
string segment,
IContractResolver contractResolver,
@@ -224,7 +224,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- private bool TryConvertValue(
+ protected virtual bool TryConvertValue(
object originalValue,
Type listTypeArgument,
string segment,
@@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- private bool TryGetListTypeArgument(IList list, out Type listTypeArgument, out string errorMessage)
+ protected virtual bool TryGetListTypeArgument(IList list, out Type listTypeArgument, out string errorMessage)
{
// Arrays are not supported as they have fixed size and operations like Add, Insert do not make sense
var listType = list.GetType();
@@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private bool TryGetPositionInfo(
+ protected virtual bool TryGetPositionInfo(
IList list,
string segment,
OperationType operationType,
@@ -318,7 +318,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
}
}
- private struct PositionInfo
+ protected struct PositionInfo
{
public PositionInfo(PositionType type, int index)
{
@@ -330,7 +330,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
public int Index { get; }
}
- private enum PositionType
+ protected enum PositionType
{
Index, // valid index
EndOfList, // '-'
@@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
OutOfBounds
}
- private enum OperationType
+ protected enum OperationType
{
Add,
Remove,
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs
index 8994f0aa52..a988afa300 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/ObjectVisitor.cs
@@ -3,19 +3,38 @@
using System;
using System.Collections;
+using Microsoft.AspNetCore.JsonPatch.Adapters;
using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class ObjectVisitor
{
+ private readonly IAdapterFactory _adapterFactory;
private readonly IContractResolver _contractResolver;
private readonly ParsedPath _path;
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The path of the JsonPatch operation
+ /// The .
public ObjectVisitor(ParsedPath path, IContractResolver contractResolver)
+ :this(path, contractResolver, new AdapterFactory())
{
+ }
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The path of the JsonPatch operation
+ /// The .
+ /// The to use when creating adaptors.
+ public ObjectVisitor(ParsedPath path, IContractResolver contractResolver, IAdapterFactory adapterFactory)
+ {
_path = path;
_contractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
+ _adapterFactory = adapterFactory ?? throw new ArgumentNullException(nameof(adapterFactory));
}
public bool TryVisit(ref object target, out IAdapter adapter, out string errorMessage)
@@ -48,25 +67,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
private IAdapter SelectAdapter(object targetObject)
{
- var jsonContract = _contractResolver.ResolveContract(targetObject.GetType());
-
- if (targetObject is IList)
- {
- return new ListAdapter();
- }
- else if (jsonContract is JsonDictionaryContract jsonDictionaryContract)
- {
- var type = typeof(DictionaryAdapter<,>).MakeGenericType(jsonDictionaryContract.DictionaryKeyType, jsonDictionaryContract.DictionaryValueType);
- return (IAdapter)Activator.CreateInstance(type);
- }
- else if (jsonContract is JsonDynamicContract)
- {
- return new DynamicObjectAdapter();
- }
- else
- {
- return new PocoAdapter();
- }
+ return _adapterFactory.Create(targetObject, _contractResolver);
}
}
}
diff --git a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs
index 0eee0fc889..5ba3e5587b 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/Internal/PocoAdapter.cs
@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
{
public class PocoAdapter : IAdapter
{
- public bool TryAdd(
+ public virtual bool TryAdd(
object target,
string segment,
IContractResolver contractResolver,
@@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryGet(
+ public virtual bool TryGet(
object target,
string segment,
IContractResolver contractResolver,
@@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryRemove(
+ public virtual bool TryRemove(
object target,
string segment,
IContractResolver contractResolver,
@@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryReplace(
+ public virtual bool TryReplace(
object target,
string segment,
IContractResolver
@@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryTest(
+ public virtual bool TryTest(
object target,
string segment,
IContractResolver
@@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return true;
}
- public bool TryTraverse(
+ public virtual bool TryTraverse(
object target,
string segment,
IContractResolver contractResolver,
@@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return false;
}
- private bool TryGetJsonProperty(
+ protected virtual bool TryGetJsonProperty(
object target,
IContractResolver contractResolver,
string segment,
@@ -220,7 +220,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
return false;
}
- private bool TryConvertValue(object value, Type propertyType, out object convertedValue)
+ protected virtual bool TryConvertValue(object value, Type propertyType, out object convertedValue)
{
var conversionResult = ConversionResultProvider.ConvertTo(value, propertyType);
if (!conversionResult.CanBeConverted)
diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs
index b6539caae8..1888ea6b4b 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocument.cs
@@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.JsonPatch
throw new ArgumentNullException(nameof(objectToApplyTo));
}
- ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null));
+ ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, null, new AdapterFactory()));
}
///
@@ -183,13 +183,28 @@ namespace Microsoft.AspNetCore.JsonPatch
/// Object to apply the JsonPatchDocument to
/// Action to log errors
public void ApplyTo(object objectToApplyTo, Action logErrorAction)
+ {
+ ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction);
+ }
+
+ ///
+ /// Apply this JsonPatchDocument
+ ///
+ /// Object to apply the JsonPatchDocument to
+ /// IObjectAdapter instance to use when applying
+ /// Action to log errors
+ public void ApplyTo(object objectToApplyTo, IObjectAdapter adapter, Action logErrorAction)
{
if (objectToApplyTo == null)
{
throw new ArgumentNullException(nameof(objectToApplyTo));
}
- var adapter = new ObjectAdapter(ContractResolver, logErrorAction);
+ if (adapter == null)
+ {
+ throw new ArgumentNullException(nameof(adapter));
+ }
+
foreach (var op in Operations)
{
try
diff --git a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs
index 8ae1430185..3db0aac458 100644
--- a/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs
+++ b/src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs
@@ -697,7 +697,7 @@ namespace Microsoft.AspNetCore.JsonPatch
throw new ArgumentNullException(nameof(objectToApplyTo));
}
- ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null));
+ ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, null, new AdapterFactory()));
}
///
@@ -706,13 +706,28 @@ namespace Microsoft.AspNetCore.JsonPatch
/// Object to apply the JsonPatchDocument to
/// Action to log errors
public void ApplyTo(TModel objectToApplyTo, Action logErrorAction)
+ {
+ ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction);
+ }
+
+ ///
+ /// Apply this JsonPatchDocument
+ ///
+ /// Object to apply the JsonPatchDocument to
+ /// IObjectAdapter instance to use when applying
+ /// Action to log errors
+ public void ApplyTo(TModel objectToApplyTo, IObjectAdapter adapter, Action logErrorAction)
{
if (objectToApplyTo == null)
{
throw new ArgumentNullException(nameof(objectToApplyTo));
}
- var adapter = new ObjectAdapter(ContractResolver, logErrorAction);
+ if (adapter == null)
+ {
+ throw new ArgumentNullException(nameof(adapter));
+ }
+
foreach (var op in Operations)
{
try
diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs
new file mode 100644
index 0000000000..1e961c29e9
--- /dev/null
+++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/AdapterFactoryTests.cs
@@ -0,0 +1,73 @@
+using Microsoft.AspNetCore.JsonPatch.Adapters;
+using Microsoft.AspNetCore.JsonPatch.Internal;
+using Moq;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.JsonPatch.Test.Adapters
+{
+ public class AdapterFactoryTests
+ {
+ [Fact]
+ public void GetListAdapterForListTargets()
+ {
+ // Arrange
+ AdapterFactory factory = new AdapterFactory();
+
+ //Act:
+ IAdapter adapter = factory.Create(new List(), new DefaultContractResolver());
+
+ // Assert
+ Assert.Equal(typeof(ListAdapter), adapter.GetType());
+ }
+
+ [Fact]
+ public void GetDictionaryAdapterForDictionaryObjects()
+ {
+ // Arrange
+ AdapterFactory factory = new AdapterFactory();
+
+ //Act:
+ IAdapter adapter = factory.Create(new Dictionary(), new DefaultContractResolver());
+
+ // Assert
+ Assert.Equal(typeof(DictionaryAdapter), adapter.GetType());
+ }
+
+ private class PocoModel
+ {}
+
+
+ [Fact]
+ public void GetPocoAdapterForGenericObjects()
+ {
+ // Arrange
+ AdapterFactory factory = new AdapterFactory();
+
+ //Act:
+ IAdapter adapter = factory.Create(new PocoModel(), new DefaultContractResolver());
+
+ // Assert
+ Assert.Equal(typeof(PocoAdapter), adapter.GetType());
+ }
+
+
+
+ [Fact]
+ public void GetDynamicAdapterForGenericObjects()
+ {
+ // Arrange
+ AdapterFactory factory = new AdapterFactory();
+
+ //Act:
+ IAdapter adapter = factory.Create(new TestDynamicObject(), new DefaultContractResolver());
+
+ // Assert
+ Assert.Equal(typeof(DynamicObjectAdapter), adapter.GetType());
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs
new file mode 100644
index 0000000000..08371f25c6
--- /dev/null
+++ b/test/Microsoft.AspNetCore.JsonPatch.Test/Adapters/TestDynamicObject.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Text;
+
+namespace Microsoft.AspNetCore.JsonPatch.Test.Adapters
+{
+ public class TestDynamicObject : DynamicObject
+ { }
+}