/// <summary> /// Saves a node to the XML file. /// </summary> /// <param name="root">The XML node we want to attach the node to.</param> /// <param name="node">The node we want to save.</param> protected void SaveNode(XmlElement root, Node node) { // allow the node to process its attributes in preparation of the save node.PreSave(_node); // store the class we have to create when loading XmlElement elem = _xmlfile.CreateElement("Node"); elem.SetAttribute("Class", node.GetType().FullName); // save attributes IList <DesignerPropertyInfo> properties = node.GetDesignerProperties(); for (int p = 0; p < properties.Count; ++p) { if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { elem.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(node)); } } // append node to root root.AppendChild(elem); // save comment if (node.CommentObject != null) { XmlElement comment = _xmlfile.CreateElement("Comment"); properties = node.CommentObject.GetDesignerProperties(); for (int p = 0; p < properties.Count; ++p) { if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { comment.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(node.CommentObject)); } } elem.AppendChild(comment); } // save events foreach (Nodes.Node.SubItem sub in node.SubItems) { if (sub is Nodes.Node.SubItemEvent) { Events.Event ne = ((Nodes.Node.SubItemEvent)sub).Event; XmlElement evnt = _xmlfile.CreateElement("Event"); evnt.SetAttribute("Class", ne.GetType().FullName); // save attributes properties = ne.GetDesignerProperties(); for (int p = 0; p < properties.Count; ++p) { if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave)) { elem.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(ne)); } } elem.AppendChild(evnt); } } // save children if allowed. Disallowed for referenced behaviours. if (node.SaveChildren) { // save connectors foreach (Nodes.Node.Connector connector in node.Connectors) { // if we have no children to store we can skip the connector if (connector.ChildCount < 1) { continue; } XmlElement conn = _xmlfile.CreateElement("Connector"); conn.SetAttribute("Identifier", connector.Identifier); elem.AppendChild(conn); // save their children for (int i = 0; i < connector.ChildCount; ++i) { SaveNode(conn, connector.GetChild(i)); } } } }
/// <summary> /// Finds the correct Apply() method in the AggregateRoot and call it to apply changes to state /// </summary> /// <param name="event">The event to handle</param> /// <param name="isNew">Is this a new Event</param> private void HandleEvent(Events.Event @event, bool isNew) { //All state changes to AggregateRoot must happen via the Apply method //Make sure the right Apply method is called with the right type. //We will use reflection for this. //TODO: I tried dynamic object for this but ran into some issues. Give it a try using dynamics again. try { object[] args = new object[] { @event }; var method = ((object)this).GetType().GetMethod("Apply", new Type[] { @event.GetType() }); //Find the right method method.Invoke(this, args); //invoke with the event as argument if (isNew) { _changes.Add(@event); //only add to the events collection if it's a new event } } catch (Exception ex) { throw new EventHandlerApplyMethodMissingException(ex.Message); } }