Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json\Serialization\DynamicValueProvider.cs

Symbol Coverage: 90.48% (19 of 21)

Branch Coverage: 85.71% (12 of 14)

Cyclomatic Complexity Avg: 2.67 Max:5

Code Lines: 21


L V Source
1
#region License
2
// Copyright (c) 2007 James Newton-King
3
//
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
11
// conditions:
12
//
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
15
//
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
24
#endregion
25

  
26
#if !PocketPC && !SILVERLIGHT
27
using System;
28
using System.Collections.Generic;
29
using System.Linq;
30
using System.Text;
31
using System.Reflection;
32
using Newtonsoft.Json.Utilities;
33
using System.Globalization;
34

  
35
namespace Newtonsoft.Json.Serialization
36
{
37
  /// <summary>
38
  /// Get and set values for a <see cref="MemberInfo"/> using dynamic methods.
39
  /// </summary>
40
  public class DynamicValueProvider : IValueProvider
41
  {
42
    private readonly MemberInfo _memberInfo;
43
    private Func<object, object> _getter;
44
    private Action<object, object> _setter;
45

  
46
    /// <summary>
47
    /// Initializes a new instance of the <see cref="DynamicValueProvider"/> class.
48
    /// </summary>
49
    /// <param name="memberInfo">The member info.</param>
50
 598
    public DynamicValueProvider(MemberInfo memberInfo)
51
    {
52
 598
      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
53
 598
      _memberInfo = memberInfo;
54
 598
    }
55

  
56
    /// <summary>
57
    /// Sets the value.
58
    /// </summary>
59
    /// <param name="target">The target to set the value on.</param>
60
    /// <param name="value">The value to set on the target.</param>
61
    public void SetValue(object target, object value)
62
    {
63
      try
64
      {
65
 160595
        if (_setter == null)
66
 284
          _setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(_memberInfo);
67

  
68
#if DEBUG
69
        // dynamic method doesn't check whether the type is 'legal' to set
70
        // add this check for unit tests
71
 160595
        if (value == null)
72
        {
73
 46
          if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo)))
74
 0
            throw new Exception("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo));
75
        }
76
 160549
        else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
77
        {
78
 0
            throw new Exception("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
79
        }
80
#endif
81

  
82
 160595
        _setter(target, value);
83
      }
84
 3
      catch (Exception ex)
85
      {
86
 3
        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
87
      }
88
 160592
    }
89

  
90
    /// <summary>
91
    /// Gets the value.
92
    /// </summary>
93
    /// <param name="target">The target to get the value from.</param>
94
    /// <returns>The value.</returns>
95
    public object GetValue(object target)
96
    {
97
      try
98
      {
99
 468966
        if (_getter == null)
100
 375
          _getter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(_memberInfo);
101

  
102
 468966
        return _getter(target);
103
      }
104
 5
      catch (Exception ex)
105
      {
106
 5
        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
107
      }
108
 468961
    }
109
  }
110
}
111
#endif