In prevoius article we designed a base architecture to work with Contexts and Context Trees, but what if we want to create tree structure based on some data. Current Context interface can't provide suitable interface to interact with data, so we need to design descandand class to abstract data interaction and requisition for contexts.
There are some variaties of Context usages we can face due implementing features:

  • Context may use some specified data for it's logic

Based on conclusions above we need some generic implementation of data dependent context. Also passed data can be required or not, so we also need to figure it out.
Let's write some code:

    /// <summary>
    ///     Data dependent context which allows to change data at runtime.
    /// </summary>
    /// <typeparam name="TData"> Type of data depend to. </typeparam>
    public class Context<TData> : Context
    {
        private TData _dataSource;

        /// <summary>
        ///     Accessor and setter to current data source instance.
        /// </summary>
        public TData DataSource
        {
            get { return _dataSource; }
            set
            {
                if (_dataSource == null && value == null) return;
                if (_dataSource != null && value != null && _dataSource.Equals(value)) return;
                _dataSource = value;
                DataSourceChanged();
            }
        }
        
        /// <summary>
        ///     Creates new context with no specified data.
        /// </summary>
        public Context()
        {
            
        }

        /// <summary>
        ///     Creates new context with data specified, will cause  invocation.
        /// </summary>
        /// <param name="data"></param>
        public Context(TData data)
        {
            DataSource = data;
        }
        
        /// <summary>
        ///     Calls when data cource were changed.
        /// </summary>
        protected virtual void DataSourceChanged()
        {

        }
    }

This generic implementation allows to create data dependent contexts. I also added extra DataSourceChanged method to handle data changing due context lifetime. It suitable context trees when every child context depends on some child data of parent's data.
And now let's take a look how we can work with it:

        public Example()
        {
            var dataInternal = new DataInternal { Field = "internal" };
            var data = new Data { Field = "data", Internal = dataInternal };

            var dc = new DataContext(data);
            var dcc = dc.Child;

            // dc.DataSource now references data instance and field is "data"
            // dcc.DataSource now references data.Internal instance and field is "internal"

            var dataInternal2 = new DataInternal { Field = "internal2" };
            var data2 = new Data { Field = "data2", Internal = dataInternal2 };

            dc.DataSource = data2;

            // dc.DataSource now references data2 instance and field is "data2"
            // dcc.DataSource now references data2.Internal instance and field is "internal2"
        }

As you can see it's quite simple and flexible to be used in bunch of different ways, but first of all it was designed to make complex hierarchy with big amount of inbound contexts.