using System; using System.Collections.Generic; namespace Chernobyl.DesignPatterns.Extension { /// /// An that takes a list of /// and attaches them to /// another instance of some type specified by the /// generic argument. The instance to be /// extended is received through the method. /// Basically, this class attaches and detaches extensions from a single /// instance when requested by either an event (using the /// ) or just a method (using the /// ) method. When or /// is called, this class detaches /// all of the extensions from the extended instance. /// /// The type of the instance that will be /// extended. Note that, this instance must be reference type. public class Extender : Extension where ExtendedType : class { /// /// Constructor. /// /// The extensions to attach and detach to/from /// the when requested by /// or /// (for attaching) and or /// (for detaching). public Extender(List> extensions) { Extensions = extensions; } /// /// When invoked, this method will attach all the extensions in /// to the extended object received in the /// method. /// public void Attach() { ExtendedType extended = Extended; foreach (IExtension extension in Extensions) extension.Extended = extended; } /// /// An event handler that can be attached to an event. When invoked, this /// method will attach all the extensions in to /// the extended object received in the method. /// /// The sender of the event. /// The event's arguments. public void Attach(object sender, EventArgs e) { Attach(); } /// /// When invoked, this method will detach all the extensions in /// from the extended object received in the /// method. /// public void Detach() { ExtendedType extended = Extended; foreach (IExtension extension in Extensions) extension.Extended = null; } /// /// An event handler that can be attached to an event. When invoked, this /// method will detach all the extensions in from /// the extended object received in the method. /// /// The sender of the event. /// The event's arguments. public void Detach(object sender, EventArgs e) { Detach(); } /// /// Attaches this extension to the passed in object so that is can be /// extended. /// /// The object to extend. protected override void AttachTo(ExtendedType extended) { /*no-op*/ } /// /// Removes the decorator from an object so that it is no longer extended. /// /// The object to remove the extension from. protected override void DetachFrom(ExtendedType extended) { /*no-op*/ } /// /// The extensions to attach and detach to/from the /// when requested by /// or /// (for attaching) and or /// (for detaching). /// public List> Extensions { get; private set; } } }