Skip to content

Commit 2b83a94

Browse files
Mark Schareinaoliverbock
authored andcommitted
Allow changes in dictionaries to be synced with the managed code
1 parent 4a72098 commit 2b83a94

File tree

4 files changed

+151
-1
lines changed

4 files changed

+151
-1
lines changed

Source/Noesis.Javascript/JavascriptInterop.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,18 @@ JavascriptInterop::Setter(Local<String> iName, Local<Value> iValue, const Proper
620620
wstring name = (wchar_t*) *String::Value(JavascriptContext::GetCurrentIsolate(), iName);
621621
Handle<External> external = Handle<External>::Cast(iInfo.Holder()->GetInternalField(0));
622622
JavascriptExternal* wrapper = (JavascriptExternal*) external->Value();
623-
623+
624+
System::Object^ self = wrapper->GetObject();
625+
System::Type^ type = self->GetType();
626+
if (type->IsGenericType && type->GetInterface(System::Collections::Generic::IDictionary::typeid->Name) != nullptr)
627+
{
628+
// set property for c# dictionary object
629+
System::Collections::Generic::IDictionary<System::String^, System::Object^>^ dict = (System::Collections::Generic::IDictionary<System::String^, System::Object^>^)self;
630+
System::String^ key = gcnew System::String((wchar_t*)*String::Value(iName));
631+
System::Object^ value = ConvertFromV8(iValue);
632+
dict[key] = value;
633+
}
634+
624635
// set property
625636
iInfo.GetReturnValue().Set(wrapper->SetProperty(name, iValue));
626637
}

Tests/Noesis.Javascript.Tests/AccessorInterceptorTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
22
using FluentAssertions;
33
using System;
4+
using System.Collections.Generic;
5+
using Noesis.Javascript.Tests.Proxy;
46

57
namespace Noesis.Javascript.Tests
68
{
@@ -53,6 +55,27 @@ public void AccessingByIndexAPropertyInAManagedObject()
5355
_context.Run("myObject[99] == 'Value 99'").Should().BeOfType<bool>().Which.Should().BeTrue();
5456
}
5557

58+
class ClassWithDictionary
59+
{
60+
public JavaScriptDictionary<string, object> prop { get; set; }
61+
}
62+
63+
[TestMethod]
64+
public void AccessingDictionaryInManagedObject()
65+
{
66+
var dict = new Dictionary<string, object> { { "bar", "33" }, { "baz", true } };
67+
ClassWithDictionary testObj = new ClassWithDictionary() { prop = new JavaScriptDictionary<string, object>(dict) };
68+
69+
_context.SetParameter("test", testObj);
70+
var result = _context.Run(@"test.prop.foo = 42; test.prop.baz = false;");
71+
var testObjResult = (ClassWithDictionary)_context.GetParameter("test");
72+
73+
testObjResult.prop.Count.Should().Be(3);
74+
testObjResult.prop["foo"].Should().Be(42);
75+
testObjResult.prop["bar"].Should().Be("33");
76+
testObjResult.prop["baz"].Should().Be(false);
77+
}
78+
5679
class ClassWithProperty
5780
{
5881
public string MyProperty { get; set; }

Tests/Noesis.Javascript.Tests/Noesis.Javascript.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
<Compile Include="Properties\AssemblyInfo.cs" />
9393
<Compile Include="MultipleAppDomainsTest.cs" />
9494
<Compile Include="DateTest.cs" />
95+
<Compile Include="Proxy\JavaScriptDictionary.cs" />
9596
<Compile Include="VersionStringTests.cs" />
9697
</ItemGroup>
9798
<ItemGroup>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
4+
namespace Noesis.Javascript.Tests.Proxy
5+
{
6+
public class JavaScriptDictionary<K, V> : IDictionary<K, V>
7+
{
8+
9+
public JavaScriptDictionary(IDictionary<K, V> dict)
10+
{
11+
realDict = dict;
12+
}
13+
14+
private IDictionary<K, V> realDict;
15+
16+
public V this[K key]
17+
{
18+
get
19+
{
20+
return realDict[key];
21+
}
22+
set
23+
{
24+
realDict[key] = value;
25+
}
26+
}
27+
28+
public ICollection<K> Keys
29+
{
30+
get
31+
{
32+
return realDict.Keys;
33+
}
34+
}
35+
36+
public ICollection<V> Values
37+
{
38+
get
39+
{
40+
return realDict.Values;
41+
}
42+
}
43+
44+
public int Count
45+
{
46+
get
47+
{
48+
return realDict.Count;
49+
}
50+
}
51+
52+
public bool IsReadOnly
53+
{
54+
get
55+
{
56+
return realDict.IsReadOnly;
57+
}
58+
}
59+
60+
public void Add(K key, V value)
61+
{
62+
realDict.Add(key, value);
63+
}
64+
65+
public void Add(KeyValuePair<K, V> item)
66+
{
67+
realDict.Add(item);
68+
}
69+
70+
public void Clear()
71+
{
72+
realDict.Clear();
73+
}
74+
75+
public bool Contains(KeyValuePair<K, V> item)
76+
{
77+
return realDict.Contains(item);
78+
}
79+
80+
public bool ContainsKey(K key)
81+
{
82+
return realDict.ContainsKey(key);
83+
}
84+
85+
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
86+
{
87+
realDict.CopyTo(array, arrayIndex);
88+
}
89+
90+
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
91+
{
92+
return realDict.GetEnumerator();
93+
}
94+
95+
public bool Remove(K key)
96+
{
97+
return realDict.Remove(key);
98+
}
99+
100+
public bool Remove(KeyValuePair<K, V> item)
101+
{
102+
return realDict.Remove(item);
103+
}
104+
105+
public bool TryGetValue(K key, out V value)
106+
{
107+
return realDict.TryGetValue(key, out value);
108+
}
109+
110+
IEnumerator IEnumerable.GetEnumerator()
111+
{
112+
return realDict.GetEnumerator();
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)