Using the composite pattern with serialization in order to create a flexible navigation framework - Hendrik Swanepoel

Hendrik Swanepoel

Using the composite pattern with serialization in order to create a flexible navigation framework

Introduction

We all use navigation structures in our websites, some more useful than others. In a CMS system you will normally add a lot of meta data to the navigation elements, seeing that the whole point of the system is to manipulate these items and their content.

What I want to accomplish is to write a basic framework that will allow for a base navigation element that can be extended for different scenarios. In one site we would possibly only want to have description and heading properties related to the navigation objects. In another site we may want both the description and heading properties, but also an additional property, called URL.

Requirements

In order to simplify what we want to accomplish here, I'll try to draw up a list of requirements:

  • We want our objects to be related to each other in a tree like structure - for this we'll use the composite pattern (With a bit of tweaking)
  • We want all the nav objects to be able to manipulate this tree, by way of adding children and siblings to them
  • We want to be able to publish the whole structure (or part of it) to an XML file for XSL transformation
  • We want to be able to extend the base navigation easily to add our own properties to persist to our xml stores

Overview of proposed solution

  • I'll use the composite design pattern to represent the tree structure
  • I'll use serialization in order to "automate" the representation of the object in XML
  • For now, I'm not going to provide the objects with data methods - maybe for a future article

Code

 

First we'll write our base navigation class. In this class we'll have the composite logic. We'll also insert the common logic to manipulate the tree structure

 
using System;
using System.Xml.Serialization;
using System.Collections;

namespace serialization
{
/// 
/// This object will be used as the base class for other navigation elements 
/// The basic structure modifier methods will be housed here
/// 
    public class NavObject
    {
        /// 
        /// The private variables
        /// 
        private string description;
        private string heading;
        private ArrayList childNavs = new ArrayList();
        private NavObject parent;

        /// 
        /// The properties
        /// 
        public string Description
        {
            get{return description;}
            set{description = value;}
        }
        public string Heading
        {
            get{return heading;}
            set{heading = value;}
        }
        
        /// 
        /// This is ignored - because if the serializer will attempt to 
        ///parse the housing element's 
        /// properties - it will cause an infinite loop
        /// 
        [XmlIgnore]
        public NavObject Parent
        {
            set{parent = value;}
        }
    
        /// 
        /// Declare the XmlArrayItem attribute
        /// Note that all the different possible object types must be listed in here
        /// 
        /// The XmlArray attribute - specifies that we want the next item to 
///be serialized as an xmlarray
///
[XmlArrayItem(ElementName="NavObject",Type = typeof(object)),
XmlArrayItem(ElementName="AdminNavObject", Type = typeof(AdminNavObject)),
XmlArrayItem(ElementName = "SiteNavObject", Type= typeof(SiteNavObject))] [XmlArray(ElementName="Children")] public ArrayList ChildNavs { get{return childNavs;} } /// /// Adds a child to the item to the end of the child collection /// /// The item to add to the collection public void AddChild(object navElement) { ((NavObject)navElement).Parent = this; this.childNavs.Add(navElement); } /// /// Removes a child from the collection /// /// The object to remove from the collection public void RemoveChild(object navElement) { this.childNavs.Remove(navElement); } /// /// Inserts a child in the parent's collection at this items index -
///and shift all the items down after it
///
/// public void InsertPrevSibling(object navElement) { ((NavObject)navElement).Parent = this.parent; this.parent.ChildNavs.Insert(this.parent.ChildNavs.IndexOf(this), navElement); } /// /// Inserts a child in the parent's collection after this item's index /// /// public void InsertAfterSibling(object navElement) { ((NavObject)navElement).Parent = this.parent; int insertIndex = this.parent.ChildNavs.IndexOf(this) + 1; if(insertIndex > this.parent.ChildNavs.Count) { this.parent.AddChild(navElement); } else { this.parent.ChildNavs.Insert(insertIndex, navElement); } } public NavObject() { } } }

Now we'll derive a class from the base class called AdminNavObject. This class will contain extra properties which will then be persisted to the resulting xml.

 
using System;
using System.Xml.Serialization;

namespace serialization
{
    public class AdminNavObject: NavObject
    {
        /// 
        /// We just add our extra properties
        /// If it's populated at the time of serialization, it will be 
/// serialized - otherwise it will be omitted
/// We add [XmlIgnore] attributes to the properties which we want to omit
////
from the results ///
private string username; private string password; /// /// We dont want the password property to be serialized, so we use the
/// XmlIgnore attribute to exclude it
///
[XmlIgnore] public string PassWord{get{return password;} set{password = value;}} public string UserName{get{return username;} set{username = value;}} public AdminNavObject() { } } }

And just for fun, we'll create another derivative of the base object, with it's own additional properties which will be persisted to xml.

 
using System;
using System.Xml.Serialization;

namespace serialization
{
    public class SiteNavObject: NavObject
    {
        /// 
        /// We just add our extra properties
        /// If it's populated at the time of serialization, it will be serialized - 
///otherwise it will be omitted
/// We add [XmlIgnore] attributes to the properties which we want
/// to omit from the results
///
private string url; private string target; public string URL{get{return url;} set{url = value;}} public string Target{get{return target;} set{target = value;}} public SiteNavObject() { } } }

Let's look at an example that will build a tree and persist it to xml. Normally, you would get the data from a data store of some kind, and populate the tree from that.

 
using System;
using System.Xml.Serialization;
using System.IO;
using System.Collections;

namespace serialization
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            //we create a navobject base class - this can be any navobject 
//(AdminNavObject or SiteNavObject or NavObject)
NavObject o = new NavObject(); o.Description = "this is item number a - navobject"; o.Heading ="item number a"; //We add a child to the item above AdminNavObject a1 = new AdminNavObject(); a1.Description = "this is item number b - adminobject"; a1.Heading ="item number b"; o.AddChild(a1); //We add a child to the item above AdminNavObject a2 = new AdminNavObject(); a2.Description = "this is item number c - adminobject"; a2.Heading ="item number c"; a2.UserName = "HendrikSwanepoel"; a2.PassWord="MyPassword"; a1.AddChild(a2); //We add a child to the item above AdminNavObject a3= new AdminNavObject(); a3.Description = "this is item number d - adminobject"; a3.Heading ="item number d"; a2.AddChild(a3); //We add a child to the item above AdminNavObject a4= new AdminNavObject(); a4.Description = "this is item number e - adminobject"; a4.Heading ="item number e"; a2.AddChild(a4); //We insert an element after item a3 AdminNavObject a5= new AdminNavObject(); a5.Description = "this is item number f - adminobject - will be inserted between element d and e"; a5.Heading ="item number f"; a3.InsertAfterSibling(a5); //we insert an element before item a4 - which is now the last element AdminNavObject a6= new AdminNavObject(); a6.Description = "this is item number g - will be inserted before item e"; a6.Heading ="item number g"; a4.InsertPrevSibling(a6); //can add a SiteNavObject too - we add this to the root node SiteNavObject s1 = new SiteNavObject(); s1.Description = "A site nav object"; s1.Heading = "The site nav's heading"; s1.Target="_blank"; s1.URL = "http://dotnet.org.za/hendrik"; o.AddChild(s1); //We instantiate the serializer XmlSerializer x = new XmlSerializer(typeof(NavObject)); //We instantiate a stream to write the results to string fileName = Directory.GetCurrentDirectory() + "\\thexml.xml"; FileStream f = new FileStream(fileName, FileMode.Create); try { //let's serialize it x.Serialize(f, o); } finally { //Whatever happens we have to close the stream f.Close(); Console.WriteLine(fileName); Console.ReadLine(); } } } }

The resulting xml file will look like this:

 
  xml version="1.0" ?> 
- <NavObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Description>this is item number a - navobjectDescription> 
  <Heading>item number aHeading> 
- <Children>
- <AdminNavObject>
  <Description>this is item number b - adminobjectDescription> 
  <Heading>item number bHeading> 
- <Children>
- <AdminNavObject>
  <Description>this is item number c - adminobjectDescription> 
  <Heading>item number cHeading> 
- <Children>
- <AdminNavObject>
  <Description>this is item number d - adminobjectDescription> 
  <Heading>item number dHeading> 
  <Children /> 
  AdminNavObject>
- <AdminNavObject>
  <Description>this is item number f - adminobject - will be inserted between element d and eDescription> 
  <Heading>item number fHeading> 
  <Children /> 
  AdminNavObject>
- <AdminNavObject>
  <Description>this is item number g - will be inserted before item eDescription> 
  <Heading>item number gHeading> 
  <Children /> 
  AdminNavObject>
- <AdminNavObject>
  <Description>this is item number e - adminobjectDescription> 
  <Heading>item number eHeading> 
  <Children /> 
  AdminNavObject>
  Children>
  <UserName>HendrikSwanepoelUserName> 
  AdminNavObject>
  Children>
  AdminNavObject>
- <SiteNavObject>
  <Description>A site nav objectDescription> 
  <Heading>The site nav's headingHeading> 
  <Children /> 
  <URL>http://dotnet.org.za/hendrikURL> 
  <Target>_blankTarget> 
  SiteNavObject>
  Children>
  NavObject>

Posted: Apr 16 2004, 02:16 PM by hendrik | with 675 comment(s)
Filed under:

Comments

TrackBack said:

# April 16, 2004 4:22 PM

TrackBack said:

# April 18, 2004 8:39 PM

René Sprietsma said:

Hello, I played a couple of days with your example. It works pretty cool! I was wandering, is it possible to make a enhancement/method like.. I put in an indexNumber, generated with indexOf statement.. and with that number i add a child below? like .addChildUnderIndex(insertIndex, ChildtoAdd)
I am working around to do this but unfortunally my knowledge of C# has to get better... can you give an example how to implement an enhancement like this?
# January 19, 2005 3:09 PM

zxevil163 said:

cYkDHG Hi from Russia!

# March 16, 2008 11:05 PM

zxevil170 said:

FKZDZ7 [url=http://enkhnuha1.110mb.com/]enkhnuha1[/url],

<a href="http://enkhnuha1.110mb.com/">enchnuha</a>.

[url=enkhnuha1.freewebpages.org]enkhnuha1[/url],

<a href="enkhnuha1.freewebpages.org">enchnuha</a>.

# March 23, 2008 12:16 PM

numlvtitr said:

a5ZitB  <a href="vigohyjibcix.com/.../a>, [url=http://cjsjwgcupxrh.com/]cjsjwgcupxrh[/url], [link=http://nvndyqyogfee.com/]nvndyqyogfee[/link], http://ywmowcbvchzn.com/

# May 21, 2008 11:21 AM

Benn said:

# May 27, 2008 5:36 AM

Farrah said:

comment3, www.23hq.com/.../about buy zelnorm,  qzxlcc, myprofile.cos.com/buy_brahmi brahmi,  >:-), www.23hq.com/.../about buy proventil,  sok, www.23hq.com/.../about buy aciphex,  8-DD, www.23hq.com/.../about buy rogaine online,  =PPP,

# June 1, 2008 1:17 PM

Thacher said:

comment1, www.23hq.com/.../about desyrel,  252653, www.23hq.com/.../about omnicef,  >:-(, www.23hq.com/.../about plan b,  %-P, www.23hq.com/.../about buy diflucan,  %]],

# June 1, 2008 1:17 PM

Daryl said:

comment5, www.23hq.com/.../about isordil,  8], www.23hq.com/.../about lotrisone,  953235, www.23hq.com/.../about topamax,  git, www.23hq.com/.../about triphala,  htqs,

# June 11, 2008 9:39 AM

Christa said:

comment1, www.23hq.com/.../about confido,  >:D, www.23hq.com/.../about loxitane,  %PPP, www.23hq.com/.../about buy fosamax online,  mux,

# June 11, 2008 9:39 AM

Annecorinne said:

, www.imeem.com/.../98OlrkQ reosto,  14336, www.imeem.com/.../Q6M2uKk order abana,  377827,

# June 14, 2008 8:57 PM

Ola said:

, www.imeem.com/.../ivjhkIn buy cytotec online,  3823, www.imeem.com/.../wDHzHyM purchase ***+augmentation online,  kwtizr, www.imeem.com/.../nhhirz8 order starlix online,  132047,

# June 14, 2008 8:57 PM

Davie said:

comment3, www.plime.com/.../12829 abana

,  27755, www.plime.com/.../14629 insurance

,  fixd, www.plime.com/.../17874 combivent

,  4137,

# June 15, 2008 1:11 AM

Clayson said:

, www.imeem.com/.../T8nbqQK order oxytrol,  njt, www.imeem.com/.../7wAmPdV purchase fosamax,  7900, www.imeem.com/.../LCW6K7L buy viagra,  kbjd,

# June 19, 2008 11:03 AM

Caria said:

, www.imeem.com/.../0Deh7lU buy claritin,  caeda, www.imeem.com/.../g_VKF55 purchase avandamet,  fbsv, www.imeem.com/.../LCW6K7L viagra,  srdi,

# June 19, 2008 11:03 AM

Hildegaard said:

, www.imeem.com/.../1fi5dhz_tricor order tricor online,  93416, www.imeem.com/.../xxd4kff_abana order abana online,  okpj,

# June 21, 2008 11:32 AM

cheap femara said:

, www.imeem.com/.../8jkeBZ_ buy ***+augmentation,  =-OO, www.imeem.com/.../wQS7YGa cheap zyvox,  etr,

# June 24, 2008 8:31 PM

pfhkvzbks said:

eTliQA  <a href="jvghcwnmtznq.com/.../a>, [url=http://zdgcxzwnakof.com/]zdgcxzwnakof[/url], [link=http://qqhxyvvhnxkc.com/]qqhxyvvhnxkc[/link], http://ckvwnltkjrvr.com/

# June 26, 2008 12:22 PM

lopressor said:

, www.imeem.com/.../cimce9n_flagyl_er buy flagyl,  16690, www.imeem.com/.../5jelsoi_prednisone prednisone,  =[[, www.imeem.com/.../crrtmea_lotensin cheap lotensin,  23903,

# June 26, 2008 6:13 PM

clarina said:

# June 26, 2008 6:13 PM

lmekcbofwh said:

lpQ6oU  <a href="xvcbgffuikve.com/.../a>, [url=http://lkoigwdziuiy.com/]lkoigwdziuiy[/url], [link=http://girjcnydpkva.com/]girjcnydpkva[/link], http://oudyucvaynnd.com/

# July 5, 2008 12:07 AM

mescotbhp said:

pKRnBj  <a href="pbnypdrkzowd.com/.../a>, [url=http://npkhbmrbrtdf.com/]npkhbmrbrtdf[/url], [link=http://okhajobemoez.com/]okhajobemoez[/link], http://hmxyygtcvlfw.com/

# July 8, 2008 9:17 PM

Dimitri said:

Interesting, tinsit.bigheadhosting.net/cynthiaab9 rating alex rodriguez memoriblia,  8(,

# July 9, 2008 3:24 AM

Demosthenes said:

Interesting, lynetteduguay.hothostcity.com/.../index.html virgin *** photos,  >:O,

# July 9, 2008 11:11 AM

Dimitrios said:

Great site, bernicecoleman.seitenclique.net/.../index.html smart practice free shipping coupons,  >:-D,

# July 9, 2008 5:07 PM

Dimitrios said:

Interesting, paralegall.extra.hu/.../index.html bertha hurricane,  603661,

# July 10, 2008 10:55 AM

Dimitri said:

excellent resource, lesbifoto.extra.hu/.../index.html hentai sailor jupiter,  ubn,

# July 10, 2008 2:38 PM

underage cartoon grannys hentai said:

# July 10, 2008 3:24 PM

Dimitrios said:

Regards and best wishes, lesbifoto.extra.hu/.../index.html saber hentai,  4822,

# July 10, 2008 5:47 PM

Dighenis said:

excellent resource, budweiser-history-hancock-street.lessgood.com/index.html hancock county jail in indiana,  gfqcr,

# July 10, 2008 8:02 PM

Dighenis said:

excellent resource,

# July 12, 2008 10:50 AM

Demosthenes said:

excellent resource,

# July 12, 2008 11:39 AM

jesse jackson said:

jesse-jackson.itempam.com rev jesse jackson

# July 13, 2008 5:03 AM

john mccain said:

http://john-mccain.itempam.com john mccain phone number

# July 13, 2008 5:55 AM

Dighenis said:

Interesting, virginfoto.extra.hu/.../map.html virgins gallaries,  >:[,

# July 13, 2008 11:07 AM

neklgsad said:

O7vecc  <a href="dgkulbeeecly.com/.../a>, [url=http://afdffgnjcdxe.com/]afdffgnjcdxe[/url], [link=http://hfslflnvsloi.com/]hfslflnvsloi[/link], http://yetbrdtnefiv.com/

# July 13, 2008 8:49 PM

angelina jolie twins said:

http://jolie-twins.yourlet.com angelina jolie twins

# July 14, 2008 4:53 AM

maureen dowd said:

maureen-dowd.yourlet.com maureen dowd pics

# July 14, 2008 5:46 AM

jolie pitt said:

angelina-jolie-and-brad-pitt.yourlet.com andgelina jolie and bradd pitt

# July 14, 2008 6:39 AM

angelina jolie said:

angelina-jolie.yourlet.com angelina jolie butt

# July 14, 2008 9:11 AM

brooke hogan said:

brooke-hogan.yourlet.com brooke hogan pics

# July 14, 2008 11:03 AM

miss venezuela said:

miss-venezuela.yourlet.com miss venezuela 2008

# July 14, 2008 1:00 PM

miss universe said:

miss-universe-2008.yourlet.com miss venezuela universe

# July 14, 2008 1:56 PM

fannie mae freddie mac said:

fannie-mae-freddie-mac.yourlet.com fannie mae freddie mac

# July 14, 2008 2:50 PM

miss universe 2008 said:

miss-universe.yourlet.com miss universe 2008

# July 14, 2008 3:43 PM

Dighenis said:

Nice article…, puss.freehostia.com/.../map.html brooke hogan knows best,  daskx,

# July 14, 2008 6:29 PM

Dimitrios said:

Regards and best wishes, fafor.extra.hu/.../map.html bachelor of science degree,  8]]],

# July 14, 2008 7:24 PM

Dighenis said:

Interesting, scooterr.247ihost.com/.../map.html bangladeshi fucking girls,  349,

# July 14, 2008 10:22 PM

Demosthenes said:

Nice article…, george-carlin.yourlet.com/index.html george carlin monologue,  42749,

# July 15, 2008 5:15 AM

Demosthenes said:

Nice article…, megan-fox.yourlet.com/index.html megan fox thong,  whke,

# July 15, 2008 7:10 AM

Demosthenes said:

Interesting, jolie-twins.yourlet.com/index.html is angelina jolie expecting twins,  70999,

# July 15, 2008 8:07 AM

Demosthenes said:

Great site, scooterr.247ihost.com/.../index.html fucking little girls cp,  411733,

# July 15, 2008 9:05 AM

knox leon foto said:

knox-leon-foto.yourlet.com vivienne marcheline

# July 15, 2008 10:59 AM

knox leon said:

# July 15, 2008 11:58 AM

fannie mae freddie mac said:

fannie-mae-freddie-mac.yourlet.com plan for fannie mae freddie mac

# July 15, 2008 3:44 PM

knox leon said:

knox-leon-foto.yourlet.com vivienne marcheline

# July 15, 2008 4:41 PM

fannie mae freddie mac said:

fannie-mae-freddie-mac.yourlet.com freddie mac fannie mae

# July 15, 2008 6:33 PM

world youth day said:

link 2008 world youth day

# July 15, 2008 7:27 PM

rmpbitso said:

rcEdBD  <a href="lqclkqumuyul.com/.../a>, [url=http://atuuifmoxiuz.com/]atuuifmoxiuz[/url], [link=http://quphgusaupvz.com/]quphgusaupvz[/link], http://wiwwpnxpkaru.com/

# July 16, 2008 12:48 AM

obama cartoon said:

obama-cartoon.yourtodayusa.info Obama Cartoon Cover

# July 16, 2008 3:35 AM

omar khadr said:

# July 16, 2008 4:40 AM

Jocelyn Kirsch said:

jocelyn-kirsch.yourtodayusa.info Jocelyn Kirsch Edward Anderton

# July 16, 2008 5:37 AM

shark finning said:

shark-finning.yourtodayusa.info Arguments For Shark Finning

# July 16, 2008 6:35 AM

all star game said:

all-star-game.yourtodayusa.info All Star Baseball Game

# July 16, 2008 7:35 AM

current oil prices said:

oil-prices.yourtodayusa.info current oil prices

# July 16, 2008 8:34 AM

Getty Balthazar said:

balthazar-getty.yourtodayusa.info Getty Balthazar Foto

# July 16, 2008 9:32 AM

John McCain said:

# July 16, 2008 6:49 PM

Dimitri said:

Hi, joesapp.freeweb7.com/.../index.html paralegal services of northern arizona,  oswmme,

# July 16, 2008 8:58 PM

america ferrera said:

# July 17, 2008 6:49 PM

Impeachment Bush said:

# July 17, 2008 7:53 PM

Emmy Nominations 2008 said:

# July 17, 2008 8:51 PM

Brothers Massey said:

# July 17, 2008 9:50 PM

kaley cuoco said:

http://kaley-cuoco.loadtry.com Kaley Cuoco In Lingerie

# July 18, 2008 12:51 AM

tojgal said:

3Mz6k6  <a href="elfxckphdirz.com/.../a>, [url=http://ezrosjmvqcxt.com/]ezrosjmvqcxt[/url], [link=http://vdxmdzjvscra.com/]vdxmdzjvscra[/link], http://gdkgnlmxkhoz.com/

# July 18, 2008 11:55 AM

scooters for sale said:

# July 19, 2008 9:13 PM

gas scooter said:

# July 19, 2008 10:30 PM

gas scooters said:

# July 20, 2008 3:34 AM

scooters honda said:

# July 20, 2008 4:52 AM

electric scooter said:

# July 20, 2008 7:24 AM

vespa scooters said:

vespa-scooters.scootershopdirect.info used vespa motor scooters

# July 20, 2008 8:40 AM

Demosthenes said:

Regards and best wishes, thelmajones.justfree.com/.../index.html immigration paralegal salary,  006346,

# July 20, 2008 1:41 PM

Dimitri said: