Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 18bb0b3

Browse files
committed
Rename TypeReflector to TypeFields
1 parent fb6ebcf commit 18bb0b3

File tree

5 files changed

+176
-96
lines changed

5 files changed

+176
-96
lines changed

src/ServiceStack.Text/TypeFields.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@ public abstract class TypeFields
5555
{
5656
static Dictionary<Type, TypeFields> CacheMap = new Dictionary<Type, TypeFields>();
5757

58+
public static Type FactoryType = typeof(TypeFields<>);
59+
5860
public static TypeFields Get(Type type)
5961
{
6062
if (CacheMap.TryGetValue(type, out TypeFields value))
6163
return value;
6264

63-
var genericType = typeof(TypeFields<>).MakeGenericType(type);
65+
var genericType = FactoryType.MakeGenericType(type);
6466
var instanceFi = genericType.GetPublicStaticField("Instance");
6567
var instance = (TypeFields)instanceFi.GetValue(null);
6668

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using System.Threading;
5+
using ServiceStack.Reflection;
6+
using ServiceStack.Text;
7+
8+
namespace ServiceStack
9+
{
10+
[Obsolete("Use TypeProperties<T>.Instance")]
11+
public static class TypeReflector<T> { }
12+
13+
public class TypeProperties<T> : TypeProperties
14+
{
15+
public static readonly TypeProperties<T> Instance = new TypeProperties<T>();
16+
17+
static TypeProperties()
18+
{
19+
Instance.Type = typeof(T);
20+
Instance.PublicPropertyInfos = typeof(T).GetPublicProperties();
21+
foreach (var pi in Instance.PublicPropertyInfos)
22+
{
23+
try
24+
{
25+
Instance.PublicGetters[pi.Name] = pi.GetValueGetter(typeof(T));
26+
Instance.PublicSetters[pi.Name] = pi.GetValueSetter(typeof(T));
27+
Instance.PublicProperties[pi.Name] = pi;
28+
}
29+
catch (Exception ex)
30+
{
31+
Tracer.Instance.WriteError(ex);
32+
}
33+
}
34+
}
35+
}
36+
37+
public abstract class TypeProperties
38+
{
39+
static Dictionary<Type, TypeProperties> CacheMap = new Dictionary<Type, TypeProperties>();
40+
41+
public static Type FactoryType = typeof(TypeProperties<>);
42+
43+
public static TypeProperties Get(Type type)
44+
{
45+
if (CacheMap.TryGetValue(type, out TypeProperties value))
46+
return value;
47+
48+
var genericType = FactoryType.MakeGenericType(type);
49+
var instanceFi = genericType.GetPublicStaticField("Instance");
50+
var instance = (TypeProperties)instanceFi.GetValue(null);
51+
52+
Dictionary<Type, TypeProperties> snapshot, newCache;
53+
do
54+
{
55+
snapshot = CacheMap;
56+
newCache = new Dictionary<Type, TypeProperties>(CacheMap)
57+
{
58+
[type] = instance
59+
};
60+
} while (!ReferenceEquals(
61+
Interlocked.CompareExchange(ref CacheMap, newCache, snapshot), snapshot));
62+
63+
return instance;
64+
}
65+
66+
public Type Type { get; protected set; }
67+
68+
public readonly Dictionary<string, Func<object, object>> PublicGetters =
69+
new Dictionary<string, Func<object, object>>(PclExport.Instance.InvariantComparerIgnoreCase);
70+
71+
public readonly Dictionary<string, Action<object, object>> PublicSetters =
72+
new Dictionary<string, Action<object, object>>(PclExport.Instance.InvariantComparerIgnoreCase);
73+
74+
public readonly Dictionary<string, PropertyInfo> PublicProperties =
75+
new Dictionary<string, PropertyInfo>(PclExport.Instance.InvariantComparerIgnoreCase);
76+
77+
public PropertyInfo[] PublicPropertyInfos { get; protected set; }
78+
79+
public PropertyInfo GetPublicProperty(string name)
80+
{
81+
foreach (var pi in PublicPropertyInfos)
82+
{
83+
if (pi.Name == name)
84+
return pi;
85+
}
86+
return null;
87+
}
88+
89+
public Func<object, object> GetPublicGetter(PropertyInfo pi)
90+
{
91+
if (pi == null)
92+
return null;
93+
94+
return PublicGetters.TryGetValue(pi.Name, out Func<object, object> fn)
95+
? fn
96+
: pi.GetValueGetter();
97+
}
98+
99+
public Func<object, object> GetPublicGetter(string name)
100+
{
101+
if (name == null)
102+
return null;
103+
104+
return PublicGetters.TryGetValue(name, out Func<object, object> fn)
105+
? fn
106+
: null;
107+
}
108+
109+
public Action<object, object> GetPublicSetter(PropertyInfo pi)
110+
{
111+
if (pi == null)
112+
return null;
113+
114+
return PublicSetters.TryGetValue(pi.Name, out Action<object, object> fn)
115+
? fn
116+
: pi.GetValueSetter();
117+
}
118+
119+
public Action<object, object> GetPublicSetter(string name)
120+
{
121+
if (name == null)
122+
return null;
123+
124+
return PublicSetters.TryGetValue(name, out Action<object, object> fn)
125+
? fn
126+
: null;
127+
}
128+
}
129+
}

src/ServiceStack.Text/TypeReflector.cs

Lines changed: 0 additions & 94 deletions
This file was deleted.

tests/ServiceStack.Text.Tests/TypeFieldsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ServiceStack.Text.Tests
44
{
55
public class TypeFieldsTests
66
{
7-
(string s, int i, long l, double d) CreateValueTuple() =>
7+
static (string s, int i, long l, double d) CreateValueTuple() =>
88
("foo", 1, 2, 3.3);
99

1010
[Test]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using NUnit.Framework;
2+
3+
namespace ServiceStack.Text.Tests
4+
{
5+
class TypedTuple
6+
{
7+
public string S { get; set; }
8+
public int I { get; set; }
9+
public long L { get; set; }
10+
public double D { get; set; }
11+
}
12+
13+
public class TypePropertiesTests
14+
{
15+
static TypedTuple CreateTypedTuple() =>
16+
new TypedTuple { S = "foo", I = 1, L = 2, D = 3.3 };
17+
18+
[Test]
19+
public void Can_cache_ValueTuple_field_accessors()
20+
{
21+
var typeProperties = TypeProperties.Get(typeof(TypedTuple));
22+
23+
var oTuple = (object)CreateTypedTuple();
24+
25+
typeProperties.GetPublicSetter("S")(oTuple, "bar");
26+
typeProperties.GetPublicSetter("I")(oTuple, 10);
27+
typeProperties.GetPublicSetter("L")(oTuple, 20L);
28+
typeProperties.GetPublicSetter("D")(oTuple, 4.4d);
29+
30+
Assert.That(typeProperties.GetPublicGetter("S")(oTuple), Is.EqualTo("bar"));
31+
Assert.That(typeProperties.GetPublicGetter("I")(oTuple), Is.EqualTo(10));
32+
Assert.That(typeProperties.GetPublicGetter("L")(oTuple), Is.EqualTo(20));
33+
Assert.That(typeProperties.GetPublicGetter("D")(oTuple), Is.EqualTo(4.4));
34+
35+
var tuple = (TypedTuple)oTuple;
36+
37+
Assert.That(tuple.S, Is.EqualTo("bar"));
38+
Assert.That(tuple.I, Is.EqualTo(10));
39+
Assert.That(tuple.L, Is.EqualTo(20));
40+
Assert.That(tuple.D, Is.EqualTo(4.4));
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)