public override View this[string key] { get { key = _keyExchanger(key); // if the view we have if (!ChildItems.ContainsKey(key)) { var _key = (TKey)(object)key; // var x = Dictionary[_key]; // if (Dictionary.ContainsKey(_key)) { var accessor = new Accessor(() => Dictionary[_key], v => Dictionary[_key] = (TVal)v); var childMap = new ValueMap <object>(key, (p, v) => accessor, null); childMap.GetMacroValue += (name, context) => { return(name == "ElementId" || name == MemberName?key.SingleItemAsEnumerable() : null); }; MergeChild(ParentView, new View(childMap)); // } } InitializeChildItem(ChildItems[key]); return(ChildItems[key]); } set { InitializeChildItem(value); key = _keyExchanger(key); base[key] = value; } }
protected internal virtual void MergeChild(View thisView, View childView) { if (childView._map is ElementMap) { MergeElement(childView); return; } var name = childView._map.MemberName; // ensure this child's parent is set correctly. childView.ParentView = thisView; //_thisView = thisView; if (!ChildItems.ContainsKey(name)) { // before adding this, let's check if it's a node map that has // if (childView._map is NodeMap) { if ((childView._map as NodeMap)._node is ExpansionPropertyNode) { // this node is a placeholder for an object expansion. var iterator = ((childView._map as NodeMap)._node as ExpansionPropertyNode).ObjectIterator; AddChildRoutes(iterator.GetContents(thisView)); return; } } // we're first -- add it to the view, and get out. // childView.ParentReference = () => ReferenceValue; Add(name, childView); return; } // modifying this view var currentView = ChildItems[name]; currentView.ParentView = thisView; if (currentView._map._resolveValue == RESOLVED) { Debugger.Break(); } if (childView._map._resolveValue == RESOLVED) { Debugger.Break(); } // first, copy over any property that is there. if (childView.HasProperty) { // currentView.AggregatePropertyNode.InsertRange(0, childView.AggregatePropertyNode); currentView.AggregatePropertyNode.AddRange(childView.AggregatePropertyNode); } if (childView._map._aliasHistory != null && currentView._map._aliasHistory != null) { childView._map._aliasHistory.ForEach(x => currentView._map._aliasHistory.Add(x)); } childView._map._aliasHistory = (currentView._map._aliasHistory = (currentView._map._aliasHistory ?? childView._map._aliasHistory)); // copy aliases if (childView._aliases.IsValueCreated) { currentView._aliases.Value.AddRange(childView._aliases.Value); } // copy node metadata if (childView._metadata.IsValueCreated) { currentView._metadata.Value.AddRange(childView._metadata.Value); } currentView.SourceLocations = currentView.SourceLocations.Union(childView.SourceLocations); if (childView.GetType().IsGenericType&& !currentView.GetType().IsGenericType) { // the new child view has a more specific type. // we need to abandon the old view, and use the new child for the view. // View old = currentView; // currentView = childView; // childView = old; // ChildItems[name] = currentView; } // if the child view map is replaceable, then simply steal it's child routes if (childView._map is IReplaceable) { //Console.WriteLine("Leveraging {0}/{1}\r\n into {2}/{3}", childView._map.Identity, childView._map.GetType().Name, currentView._map.Identity, currentView._map.GetType().Name); currentView.FallbackRoute = currentView.FallbackRoute ?? childView.FallbackRoute; currentView._map.Active = childView._map.Active || currentView._map.Active; if (childView._map.Initializers.IsValueCreated) { currentView._map.AddChildRoutes(childView._map.Initializers.Value); } // childView._map.GetMacroValue += currentView._map.GetMacroValue; // currentView._map.GetMacroValue = childView._map.GetMacroValue; foreach (var key in currentView._map.Keys) { currentView._map[key].ParentView = currentView; } return; } // if this current view map is replaceable, then let's go the other way. if (currentView._map is IReplaceable) { // Console.WriteLine("Replacing {0}/{1}\r\n with {2}/{3}", currentView._map.Identity, currentView._map.GetType().Name, childView._map.Identity, childView._map.GetType().Name); currentView.FallbackRoute = currentView.FallbackRoute ?? childView.FallbackRoute; var oldMap = currentView._map; var newMap = childView._map; currentView._map = newMap; newMap._thisView = oldMap._thisView; newMap.ParentView = thisView; //if (oldMap._childItems != null && oldMap.Count > 0) { // if (childView._map._childItems == null || childView._map._childItems.Count == 0) { // childView._map._childItems = oldMap._childItems; //} //} newMap.Active = newMap.Active || oldMap.Active; if (newMap.Initializers.IsValueCreated) { oldMap.AddChildRoutes(newMap.Initializers.Value); } newMap.Initializers = oldMap.Initializers; // newMap._parentReferenceValue = oldMap._parentReferenceValue; newMap.GetMacroValue += oldMap.GetMacroValue; // and move any existing children over to the new map. foreach (var key in oldMap.Keys) { newMap.Add(key, oldMap[key]); } foreach (var key in newMap.Keys) { newMap[key].ParentView = currentView; } newMap._resolveValue = oldMap._resolveValue; // handle any Elements oldMap.CopyElementsTo(newMap); return; } if (currentView._map is ValueMap <object> && childView._map is ValueMap <object> ) { currentView._map.Active = childView._map.Active || currentView._map.Active; if (childView._map.Initializers.IsValueCreated) { currentView._map.AddChildRoutes(childView._map.Initializers.Value); } currentView._map.GetMacroValue += childView._map.GetMacroValue; return; } // if neither is replaceable, then we're in a kind of pickle. #if DEBUG throw new ClrPlusException("Neither map is replaceable [{0}] vs [{1}]".format(currentView._map.Identity, childView._map.MemberName)); #else throw new ClrPlusException("Neither map is replaceable [{0}] vs [{1}]".format(currentView._map.MemberName, childView._map.MemberName)); #endif }