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; }
}
}