diff --git a/DynamORM/DynamicExpando.cs b/DynamORM/DynamicExpando.cs new file mode 100644 index 0000000..411e5f1 --- /dev/null +++ b/DynamORM/DynamicExpando.cs @@ -0,0 +1,151 @@ +/* + * DynamORM - Dynamic Object-Relational Mapping library. + * Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Dynamic; +using System.Collections.Concurrent; + +namespace DynamORM +{ + /// Dynamic expando is a simple and temporary class to resolve memory leaks inside ExpandoObject. + public class DynamicExpando : DynamicObject, IDictionary, ICollection>, IEnumerable>, IEnumerable + { + private Dictionary _data = new Dictionary(); + + /// Initializes a new instance of the class. + public DynamicExpando() + { + } + + /// Tries to get member value. + /// Returns true, if get member was tryed, false otherwise. + /// The context binder. + /// The invokation result. + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + result = _data.TryGetValue(binder.Name); + + return true; + } + + /// Tries to set member. + /// Returns true, if set member was tryed, false otherwise. + /// The context binder. + /// Value which will be set. + public override bool TrySetMember(SetMemberBinder binder, object value) + { + _data[binder.Name] = value; + + return true; + } + + #region IDictionary implementation + + bool IDictionary.ContainsKey(string key) + { + return _data.ContainsKey(key); + } + + void IDictionary.Add(string key, object value) + { + _data.Add(key, value); + } + + bool IDictionary.Remove(string key) + { + return _data.Remove(key); + } + + bool IDictionary.TryGetValue(string key, out object value) + { + return _data.TryGetValue(key, out value); + } + + object IDictionary.this [string index] { get { return _data[index]; } set { _data[index] = value; } } + + ICollection IDictionary.Keys { get { return _data.Keys; } } + + ICollection IDictionary.Values { get { return _data.Values; } } + + #endregion + + #region ICollection implementation + + void ICollection>.Add(KeyValuePair item) + { + ((ICollection>)_data).Add(item); + } + + void ICollection>.Clear() + { + _data.Clear(); + } + + bool ICollection>.Contains(KeyValuePair item) + { + return ((ICollection>)_data).Contains(item); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((ICollection>)_data).CopyTo(array, arrayIndex); + } + + bool ICollection>.Remove(KeyValuePair item) + { + return ((ICollection>)_data).Remove(item); + } + + int ICollection>.Count{ get { return _data.Count; } } + + bool ICollection>.IsReadOnly { get { return ((ICollection>)_data).IsReadOnly; } } + + #endregion + + #region IEnumerable implementation + + IEnumerator> IEnumerable>.GetEnumerator() + { + return _data.GetEnumerator(); + } + + #endregion + + #region IEnumerable implementation + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)_data).GetEnumerator(); + } + + #endregion + } +} +