From 45000223b2d5d7b4940cdd41f99d68bec7da767e Mon Sep 17 00:00:00 2001 From: Bastian Buchholz Date: Fri, 1 Dec 2017 10:56:26 +0100 Subject: [PATCH] support exchanging values on DynamicViewBag across AppDomains fixes #487 --- .../Common/CrossAppDomainDictionary.cs | 121 ++++++++++++++++++ .../RazorEngine.Core/RazorEngine.Core.csproj | 1 + .../Templating/DynamicViewBag.cs | 3 +- .../IsolatedRazorEngineServiceTestFixture.cs | 17 +++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 src/source/RazorEngine.Core/Common/CrossAppDomainDictionary.cs diff --git a/src/source/RazorEngine.Core/Common/CrossAppDomainDictionary.cs b/src/source/RazorEngine.Core/Common/CrossAppDomainDictionary.cs new file mode 100644 index 00000000..c8316488 --- /dev/null +++ b/src/source/RazorEngine.Core/Common/CrossAppDomainDictionary.cs @@ -0,0 +1,121 @@ +using System.Collections; +using System.Collections.Generic; + +namespace RazorEngine.Common +{ + internal class CrossAppDomainDictionary : CrossAppDomainObject, IDictionary + { + #region Fields + + private readonly IDictionary _dict; + + #endregion + + #region Constructor + + public CrossAppDomainDictionary() + { + _dict = new Dictionary(); + } + + public CrossAppDomainDictionary(int capacity) + { + _dict = new Dictionary(capacity); + } + + public CrossAppDomainDictionary(IEqualityComparer comparer) + { + _dict = new Dictionary(comparer); + } + + public CrossAppDomainDictionary(IDictionary dictionary) + { + _dict = new Dictionary(dictionary); + } + + public CrossAppDomainDictionary(int capacity, IEqualityComparer comparer) + { + _dict = new Dictionary(capacity, comparer); + } + + public CrossAppDomainDictionary(IDictionary dictionary, IEqualityComparer comparer) + { + _dict = new Dictionary(dictionary, comparer); + } + + #endregion + + #region Properties + + public TValue this[TKey key] { get { return _dict[key]; } set { _dict[key] = value; } } + + public ICollection Keys { get { return _dict.Keys; } } + + public ICollection Values { get { return _dict.Values; } } + + public int Count { get { return _dict.Count; } } + + public bool IsReadOnly { get { return _dict.IsReadOnly; } } + + #endregion + + #region Methods + + public void Add(TKey key, TValue value) + { + _dict.Add(key, value); + } + + public void Add(KeyValuePair item) + { + _dict.Add(item); + } + + public void Clear() + { + _dict.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return _dict.Contains(item); + } + + public bool ContainsKey(TKey key) + { + return _dict.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + _dict.CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() + { + return _dict.GetEnumerator(); + } + + public bool Remove(TKey key) + { + return _dict.Remove(key); + } + + public bool Remove(KeyValuePair item) + { + return _dict.Remove(item); + } + + public bool TryGetValue(TKey key, out TValue value) + { + return _dict.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _dict.GetEnumerator(); + } + + #endregion + } +} diff --git a/src/source/RazorEngine.Core/RazorEngine.Core.csproj b/src/source/RazorEngine.Core/RazorEngine.Core.csproj index 1e8c90dd..3017c8e7 100644 --- a/src/source/RazorEngine.Core/RazorEngine.Core.csproj +++ b/src/source/RazorEngine.Core/RazorEngine.Core.csproj @@ -208,6 +208,7 @@ + diff --git a/src/source/RazorEngine.Core/Templating/DynamicViewBag.cs b/src/source/RazorEngine.Core/Templating/DynamicViewBag.cs index d4592e08..c37024cc 100644 --- a/src/source/RazorEngine.Core/Templating/DynamicViewBag.cs +++ b/src/source/RazorEngine.Core/Templating/DynamicViewBag.cs @@ -1,5 +1,6 @@ namespace RazorEngine.Templating { + using RazorEngine.Common; using System; using System.Collections; using System.Collections.Generic; @@ -13,7 +14,7 @@ public class DynamicViewBag : DynamicObject { #region Fields private readonly IDictionary _dict = - new System.Collections.Generic.Dictionary(); + new CrossAppDomainDictionary(); #endregion /// /// Create a new DynamicViewBag. diff --git a/src/test/Test.RazorEngine.Core/IsolatedRazorEngineServiceTestFixture.cs b/src/test/Test.RazorEngine.Core/IsolatedRazorEngineServiceTestFixture.cs index 40a6adc2..7ed50c07 100644 --- a/src/test/Test.RazorEngine.Core/IsolatedRazorEngineServiceTestFixture.cs +++ b/src/test/Test.RazorEngine.Core/IsolatedRazorEngineServiceTestFixture.cs @@ -142,6 +142,23 @@ public void IsolatedRazorEngineService_DynamicViewBag_InSandBox() } } + /// + /// Tests that exchanging values on the viewbag works across app domains + /// + [Test] + public void IsolatedRazorEngineService_DynamicViewBag_FromSandBox() + { + using (var service = IsolatedRazorEngineService.Create(SandboxCreator)) + { + const string template = "@{ ViewBag.Test = \"TestItem\"; }"; + const string expected = "TestItem"; + dynamic viewbag = new DynamicViewBag(); + + string result = service.RunCompile(template, "test", (Type)null, (object)null, (DynamicViewBag)viewbag); + Assert.AreEqual(expected, viewbag.Test); + } + } + /// /// Tests that a simple viewbag is working. ///