using System; using System.Collections; using System.Collections.Generic; using Chernobyl.Collections.Generic; using Chernobyl.Collections.Generic.Event; using Chernobyl.Collections.Generic.Hierarchy; namespace Chernobyl.Reflection.Template { /// /// An that allows for at runtime switching of /// it's implementation and makes creating new s /// easier through the use of other implementations. /// This is an implementation of the decorator pattern /// (http://en.wikipedia.org/wiki/Decorator_pattern). /// public abstract class ComponentDecorator : IComponent { /// /// Initializes a new instance of the class. /// Note to implementors: this constructor immediately configures the /// using the /// method. This assumes the /// is ready to use. /// protected ComponentDecorator() : this(true) { } /// /// Initializes a new instance of the class. /// /// True if this instance should be configured /// immediately, false if the method /// will be invoked at a later time by the implementing type. protected ComponentDecorator(bool configure) { if (configure == true) ConfigureImplementer(); } /// /// The namespace or prefix of this component. /// public string Prefix { get { return DecoratedComponent.Prefix; } } /// /// The name of this component which can be used to generate code for /// this component. /// public virtual string CodeName { get { return DecoratedComponent.CodeName; } } /// /// The that is the parent to this /// . This will be /// added to the parent 's /// list. If this /// is already a child to another then it will /// be removed from that 's /// list. Setting null on this property /// will cause this to be removed from it's /// parent, if necessary. Note that the /// does not invoke the 's /// property because then the /// would be added to the /// 's list rather /// than this instance. /// public virtual IComponent Parent { get { return DecoratedComponent.Parent; } set { DecoratedComponent.Parent = value; } } /// /// Sub-components of this . Note that the /// does not return the /// 's /// property because then the would /// be set on the added children's property rather /// than this instance. /// public IEventCollection ComponentChildren { get { return DecoratedComponent.ComponentChildren; } } /// /// Gets or sets the name of the instance. This property is made virtual /// to allow for a name is separate from the /// . /// public string Name { get { return DecoratedComponent.Name; } set { DecoratedComponent.Name = value; } } /// /// An that iterates over an /// in depth first order (see /// http://en.wikipedia.org/wiki/Depth-first_search for more information). /// /// public IEnumerable DepthFirst { get { return DecoratedComponent.DepthFirst; } } /// /// An that iterates over an /// in breadth first order (see /// http://en.wikipedia.org/wiki/Breadth-first_search for more information). /// /// public IEnumerable BreadthFirst { get { return DecoratedComponent.BreadthFirst; } } /// /// Returns an enumerator that iterates through this /// and the tree /// underneath it. /// /// /// A that can /// be used to iterate through the tree. /// public IEnumerator GetEnumerator() { return DecoratedComponent.GetEnumerator(); } /// /// Returns an that iterates through this /// and the tree /// underneath it. /// /// /// A that can /// be used to iterate through the tree. /// IEnumerator IEnumerable.GetEnumerator() { return DecoratedComponent.GetEnumerator(); } /// /// The that "decorates" /// (http://en.wikipedia.org/wiki/Decorator_pattern) this /// . The decorator is used when this /// needs client code to refer to the /// decorator rather than this such as when /// parenting children. In the event that a decorator doesn't exist, /// this property is set to null. /// public IComponent Decorator { get { return DecoratedComponent.Decorator; } set { DecoratedComponent.Decorator = value; } } /// /// A method that must be invoked by the implementing type so this /// instance can be properly setup to work with the /// . /// protected void ConfigureImplementer() { if (_implementerConfigured == false) { if (DecoratedComponent == null) throw new Exception("The DecoratedComponent is null and cannot " + "be configured. Please pass false to this class' constructor and " + "invoke ConfigureImplementer() method when the DecoratedComponent " + "is ready."); Decorator = this; _implementerConfigured = true; } } /// /// The instance that implements the /// functionality of this class. /// protected abstract IComponent DecoratedComponent { get; } /// /// True if the method has already /// been called, false if otherwise. /// bool _implementerConfigured; } }