Skip to content

Commit 4e68795

Browse files
committed
Return true dynamic object for dynamic-component
1 parent b5440cc commit 4e68795

File tree

5 files changed

+201
-7
lines changed

5 files changed

+201
-7
lines changed

src/NHibernate.Test/NHSpecificTest/NH2664Dynamic/Fixture.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public void Query_DynamicComponent()
8383

8484
Assert.That(product, Is.Not.Null);
8585
Assert.That((object) product.Properties["Name"], Is.EqualTo("First Product"));
86+
Assert.That((object) product.Properties.Name, Is.EqualTo("First Product"));
8687
}
8788
}
8889

src/NHibernate/Properties/MapAccessor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ public sealed class MapGetter : IGetter
4848

4949
public MethodInfo Method => null;
5050

51-
public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) => Get(owner);
52-
5351
public string PropertyName => null;
5452

5553
public System.Type ReturnType => typeof(object);
5654

55+
public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) => Get(owner);
56+
5757
public object Get(object target)
5858
{
5959
switch (target)
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
4+
using NHibernate.Util;
35

46
namespace NHibernate.Tuple.Component
57
{
@@ -8,8 +10,10 @@ internal class DynamicComponentInstantiator : IInstantiator
810
{
911
public object Instantiate(object id) => Instantiate();
1012

11-
public object Instantiate() => new Dictionary<string, object>();
13+
public object Instantiate() => new DynamicDictionaryWrapper();
1214

13-
public bool IsInstance(object obj) => obj is Dictionary<string, object>;
15+
public bool IsInstance(object obj) => obj is DynamicDictionaryWrapper ||
16+
obj is IDictionary<string, object> ||
17+
obj is IDictionary;
1418
}
1519
}

src/NHibernate/Tuple/Component/DynamicMapComponentTuplizer.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using NHibernate.Properties;
3-
using System.Collections;
4-
using System.Collections.Generic;
3+
using NHibernate.Util;
54

65
namespace NHibernate.Tuple.Component
76
{
@@ -19,7 +18,7 @@ public DynamicMapComponentTuplizer(Mapping.Component component)
1918
}
2019

2120
public override System.Type MappedClass =>
22-
typeof(Dictionary<string, object>);
21+
typeof(DynamicDictionaryWrapper);
2322

2423
protected internal override IInstantiator BuildInstantiator(Mapping.Component component) =>
2524
new DynamicComponentInstantiator();
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Dynamic;
5+
6+
namespace NHibernate.Util
7+
{
8+
public class DynamicDictionaryWrapper : DynamicObject, IDictionary, IDictionary<string, object>
9+
{
10+
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
11+
12+
public override bool TryGetMember(GetMemberBinder binder, out object result)
13+
{
14+
return _data.TryGetValue(binder.Name, out result);
15+
}
16+
17+
public override bool TrySetMember(SetMemberBinder binder, object value)
18+
{
19+
_data[binder.Name] = value;
20+
return true;
21+
}
22+
23+
public override bool TryDeleteMember(DeleteMemberBinder binder)
24+
{
25+
return _data.Remove(binder.Name);
26+
}
27+
28+
public override IEnumerable<string> GetDynamicMemberNames()
29+
{
30+
return _data.Keys;
31+
}
32+
33+
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
34+
{
35+
if (indexes.Length == 1 && indexes[0] is string key)
36+
return _data.TryGetValue(key, out result);
37+
return base.TryGetIndex(binder, indexes, out result);
38+
}
39+
40+
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
41+
{
42+
if (indexes.Length == 1 && indexes[0] is string key)
43+
{
44+
_data[key] = value;
45+
return true;
46+
}
47+
return base.TrySetIndex(binder, indexes, value);
48+
}
49+
50+
public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes)
51+
{
52+
if (indexes.Length == 1 && indexes[0] is string key)
53+
return _data.Remove(key);
54+
55+
return base.TryDeleteIndex(binder, indexes);
56+
}
57+
58+
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
59+
{
60+
if (_data.TryGetValue(binder.Name, out var possibleDeligate) && possibleDeligate is Delegate @delegate)
61+
{
62+
result = @delegate.DynamicInvoke(args);
63+
return true;
64+
}
65+
66+
return base.TryInvokeMember(binder, args, out result);
67+
}
68+
69+
void IDictionary.Add(object key, object value)
70+
{
71+
((IDictionary) _data).Add(key, value);
72+
}
73+
74+
void IDictionary.Clear()
75+
{
76+
((IDictionary) _data).Clear();
77+
}
78+
79+
bool IDictionary.Contains(object key)
80+
{
81+
return ((IDictionary) _data).Contains(key);
82+
}
83+
84+
IDictionaryEnumerator IDictionary.GetEnumerator()
85+
{
86+
return ((IDictionary) _data).GetEnumerator();
87+
}
88+
89+
void IDictionary.Remove(object key)
90+
{
91+
((IDictionary) _data).Remove(key);
92+
}
93+
94+
bool IDictionary.IsFixedSize => ((IDictionary) _data).IsFixedSize;
95+
96+
bool IDictionary.IsReadOnly => ((IDictionary) _data).IsReadOnly;
97+
98+
object IDictionary.this[object key]
99+
{
100+
get => ((IDictionary) _data)[key];
101+
set => ((IDictionary) _data)[key] = value;
102+
}
103+
104+
ICollection IDictionary.Keys => ((IDictionary) _data).Keys;
105+
106+
ICollection IDictionary.Values => ((IDictionary) _data).Values;
107+
108+
IEnumerator IEnumerable.GetEnumerator()
109+
{
110+
return ((IEnumerable) _data).GetEnumerator();
111+
}
112+
113+
void ICollection.CopyTo(Array array, int index)
114+
{
115+
((ICollection) _data).CopyTo(array, index);
116+
}
117+
118+
int ICollection.Count => ((ICollection) _data).Count;
119+
120+
bool ICollection.IsSynchronized => ((ICollection) _data).IsSynchronized;
121+
122+
object ICollection.SyncRoot => ((ICollection) _data).SyncRoot;
123+
124+
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
125+
{
126+
((ICollection<KeyValuePair<string, object>>) _data).Add(item);
127+
}
128+
129+
void ICollection<KeyValuePair<string, object>>.Clear()
130+
{
131+
((ICollection<KeyValuePair<string, object>>) _data).Clear();
132+
}
133+
134+
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
135+
{
136+
return ((ICollection<KeyValuePair<string, object>>) _data).Contains(item);
137+
}
138+
139+
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
140+
{
141+
((ICollection<KeyValuePair<string, object>>) _data).CopyTo(array, arrayIndex);
142+
}
143+
144+
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
145+
{
146+
return ((ICollection<KeyValuePair<string, object>>) _data).Remove(item);
147+
}
148+
149+
int ICollection<KeyValuePair<string, object>>.Count =>
150+
((ICollection<KeyValuePair<string, object>>) _data).Count;
151+
152+
bool ICollection<KeyValuePair<string, object>>.IsReadOnly =>
153+
((ICollection<KeyValuePair<string, object>>) _data).IsReadOnly;
154+
155+
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
156+
{
157+
return ((IEnumerable<KeyValuePair<string, object>>) _data).GetEnumerator();
158+
}
159+
160+
void IDictionary<string, object>.Add(string key, object value)
161+
{
162+
((IDictionary<string, object>) _data).Add(key, value);
163+
}
164+
165+
bool IDictionary<string, object>.ContainsKey(string key)
166+
{
167+
return ((IDictionary<string, object>) _data).ContainsKey(key);
168+
}
169+
170+
bool IDictionary<string, object>.Remove(string key)
171+
{
172+
return ((IDictionary<string, object>) _data).Remove(key);
173+
}
174+
175+
bool IDictionary<string, object>.TryGetValue(string key, out object value)
176+
{
177+
return ((IDictionary<string, object>) _data).TryGetValue(key, out value);
178+
}
179+
180+
object IDictionary<string, object>.this[string key]
181+
{
182+
get => ((IDictionary<string, object>) _data)[key];
183+
set => ((IDictionary<string, object>) _data)[key] = value;
184+
}
185+
186+
ICollection<object> IDictionary<string, object>.Values => ((IDictionary<string, object>) _data).Values;
187+
188+
ICollection<string> IDictionary<string, object>.Keys => ((IDictionary<string, object>) _data).Keys;
189+
}
190+
}

0 commit comments

Comments
 (0)