Initial commit providing the AdapterFactory directly to the ObjectAdapter to all for customization of the Adapter selection and the ability to override the built in adapters to leverage their ability as much as possible.
This commit is contained in:
parent
d7ac5c57ef
commit
4d92d76b64
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// The default AdapterFactory to be used for resolving <see cref="IAdapter"/>.
|
||||
/// </summary>
|
||||
public class AdapterFactory : IAdapterFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the operations used for loading an <see cref="IAdapter"/> based on the current object and ContractResolver.
|
||||
/// </summary>
|
||||
public interface IAdapterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IAdapter"/> for the current object
|
||||
/// </summary>
|
||||
/// <param name="target">The target object</param>
|
||||
/// <param name="contractResolver">The current contract resolver</param>
|
||||
/// <returns>The needed <see cref="IAdapter"/></returns>
|
||||
IAdapter Create(object target, IContractResolver contractResolver);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,17 +18,37 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters
|
|||
/// <param name="logErrorAction">The <see cref="Action"/> for logging <see cref="JsonPatchError"/>.</param>
|
||||
public ObjectAdapter(
|
||||
IContractResolver contractResolver,
|
||||
Action<JsonPatchError> logErrorAction)
|
||||
Action<JsonPatchError> logErrorAction):
|
||||
this(contractResolver, logErrorAction, new AdapterFactory())
|
||||
{
|
||||
ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
|
||||
LogErrorAction = logErrorAction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ObjectAdapter"/>.
|
||||
/// </summary>
|
||||
/// <param name="contractResolver">The <see cref="IContractResolver"/>.</param>
|
||||
/// <param name="logErrorAction">The <see cref="Action"/> for logging <see cref="JsonPatchError"/>.</param>
|
||||
/// <param name="adapterFactory">The <see cref="IAdapterFactory"/> to use when creating adaptors.</param>
|
||||
public ObjectAdapter(
|
||||
IContractResolver contractResolver,
|
||||
Action<JsonPatchError> logErrorAction,
|
||||
IAdapterFactory adapterFactory)
|
||||
{
|
||||
ContractResolver = contractResolver ?? throw new ArgumentNullException(nameof(contractResolver));
|
||||
LogErrorAction = logErrorAction;
|
||||
AdapterFactory = adapterFactory ?? throw new ArgumentNullException(nameof(adapterFactory));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IContractResolver"/>.
|
||||
/// </summary>
|
||||
public IContractResolver ContractResolver { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IAdapterFactory"/>
|
||||
/// </summary>
|
||||
public IAdapterFactory AdapterFactory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action for logging <see cref="JsonPatchError"/>.
|
||||
/// </summary>
|
||||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
|||
{
|
||||
public class DictionaryAdapter<TKey, TValue> : 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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ObjectVisitor"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the JsonPatch operation</param>
|
||||
/// <param name="contractResolver">The <see cref="IContractResolver"/>.</param>
|
||||
public ObjectVisitor(ParsedPath path, IContractResolver contractResolver)
|
||||
:this(path, contractResolver, new AdapterFactory())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ObjectVisitor"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the JsonPatch operation</param>
|
||||
/// <param name="contractResolver">The <see cref="IContractResolver"/>.</param>
|
||||
/// <param name="adapterFactory">The <see cref="IAdapterFactory"/> to use when creating adaptors.</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -183,13 +183,28 @@ namespace Microsoft.AspNetCore.JsonPatch
|
|||
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
|
||||
/// <param name="logErrorAction">Action to log errors</param>
|
||||
public void ApplyTo(object objectToApplyTo, Action<JsonPatchError> logErrorAction)
|
||||
{
|
||||
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply this JsonPatchDocument
|
||||
/// </summary>
|
||||
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
|
||||
/// <param name="adapter">IObjectAdapter instance to use when applying</param>
|
||||
/// <param name="logErrorAction">Action to log errors</param>
|
||||
public void ApplyTo(object objectToApplyTo, IObjectAdapter adapter, Action<JsonPatchError> 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
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -706,13 +706,28 @@ namespace Microsoft.AspNetCore.JsonPatch
|
|||
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
|
||||
/// <param name="logErrorAction">Action to log errors</param>
|
||||
public void ApplyTo(TModel objectToApplyTo, Action<JsonPatchError> logErrorAction)
|
||||
{
|
||||
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction, new AdapterFactory()), logErrorAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply this JsonPatchDocument
|
||||
/// </summary>
|
||||
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
|
||||
/// <param name="adapter">IObjectAdapter instance to use when applying</param>
|
||||
/// <param name="logErrorAction">Action to log errors</param>
|
||||
public void ApplyTo(TModel objectToApplyTo, IObjectAdapter adapter, Action<JsonPatchError> 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
|
||||
|
|
|
|||
|
|
@ -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<string>(), 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<string, string>(), new DefaultContractResolver());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(typeof(DictionaryAdapter<string, string>), 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{ }
|
||||
}
|
||||
Loading…
Reference in New Issue