namespace System.Web.Mvc { using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Web.Mvc.Resources; public class ModelBinderDictionary : IDictionary { private IModelBinder _defaultBinder; private readonly Dictionary _innerDictionary = new Dictionary(); private ModelBinderProviderCollection _modelBinderProviders; public ModelBinderDictionary() : this(ModelBinderProviders.BinderProviders) { } internal ModelBinderDictionary(ModelBinderProviderCollection modelBinderProviders) { _modelBinderProviders = modelBinderProviders; } public int Count { get { return _innerDictionary.Count; } } public IModelBinder DefaultBinder { get { if (_defaultBinder == null) { _defaultBinder = new DefaultModelBinder(); } return _defaultBinder; } set { _defaultBinder = value; } } public bool IsReadOnly { get { return ((IDictionary)_innerDictionary).IsReadOnly; } } public ICollection Keys { get { return _innerDictionary.Keys; } } public IModelBinder this[Type key] { get { IModelBinder binder; _innerDictionary.TryGetValue(key, out binder); return binder; } set { _innerDictionary[key] = value; } } public ICollection Values { get { return _innerDictionary.Values; } } public void Add(KeyValuePair item) { ((IDictionary)_innerDictionary).Add(item); } public void Add(Type key, IModelBinder value) { _innerDictionary.Add(key, value); } public void Clear() { _innerDictionary.Clear(); } public bool Contains(KeyValuePair item) { return ((IDictionary)_innerDictionary).Contains(item); } public bool ContainsKey(Type key) { return _innerDictionary.ContainsKey(key); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { ((IDictionary)_innerDictionary).CopyTo(array, arrayIndex); } public IModelBinder GetBinder(Type modelType) { return GetBinder(modelType, true /* fallbackToDefault */); } public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault) { if (modelType == null) { throw new ArgumentNullException("modelType"); } return GetBinder(modelType, (fallbackToDefault) ? DefaultBinder : null); } private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder) { // Try to look up a binder for this type. We use this order of precedence: // 1. Binder returned from provider // 2. Binder registered in the global table // 3. Binder attribute defined on the type // 4. Supplied fallback binder IModelBinder binder = _modelBinderProviders.GetBinder(modelType); if (binder != null) { return binder; } if (_innerDictionary.TryGetValue(modelType, out binder)) { return binder; } binder = ModelBinders.GetBinderFromAttributes(modelType, () => String.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderDictionary_MultipleAttributes, modelType.FullName)); return binder ?? fallbackBinder; } public IEnumerator> GetEnumerator() { return _innerDictionary.GetEnumerator(); } public bool Remove(KeyValuePair item) { return ((IDictionary)_innerDictionary).Remove(item); } public bool Remove(Type key) { return _innerDictionary.Remove(key); } public bool TryGetValue(Type key, out IModelBinder value) { return _innerDictionary.TryGetValue(key, out value); } #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_innerDictionary).GetEnumerator(); } #endregion } }