using System;
using Chernobyl.Event;
namespace Chernobyl.DesignPatterns.Extension
{
///
/// The base interface for the
/// type. This type allows the to hold onto it's
/// extensions regardless of their attachment type.
///
public interface IExtension : INamed
{}
///
/// This interface provides a standardized way to extend the functionality
/// of an object dynamically at runtime. In this way, it is similar to the
/// decorator pattern (see http://en.wikipedia.org/wiki/Decorator_pattern).
/// However, this interface has several differences from the decorator
/// pattern:
/// 1) It does not require the implementation to derive from the type to
/// be extended.
/// 2) It requires that the instance to be extended be passed into a
/// method rather than a constructor.
/// 3) It allows for the extension to be removed from the instance being
/// extended.
///
/// The type to extend. If the ExtendedType
/// is an type then it is highly recommended that,
/// when an instance is extended, the extension add itself to the
/// list of the extended instance. When
/// the instance is un-extended, the extension should remove itself
/// from the extensions list of the instance.
public interface IExtension : IExtension
{
///
/// The instance being extended. Setting on instance on this property
/// will cause that instance to be extended. If a previous instance was
/// already being extended, then this extension will detach itself from
/// that instance (stop extending it) and attach itself to the new
/// instance (begin extending it). If null is set on this property then
/// the previous instance will being extended will no longer be extended
/// (if applicable). Note to implementors: it is highly recommended you
/// store the extended instance in either a
/// or a
/// to allow the extended instance to
/// be properly garbage collected.
///
TExtended Extended { get; set; }
///
/// An event that is raised right after the instance being extended has
/// changed (or whenever the property has been
/// changed).
///
event EventHandler> ExtendedChanged;
}
}