using System;
namespace Umbraco.Core.Composing
{
///
/// Indicates that a composer requires another composer.
///
///
/// This attribute is *not* inherited. This means that a composer class inheriting from
/// another composer class does *not* inherit its requirements. However, the runtime checks
/// the *interfaces* of every composer for their requirements, so requirements declared on
/// interfaces are inherited by every composer class implementing the interface.
/// When targeting a class, indicates a dependency on the composer which must be enabled,
/// unless the requirement has explicitly been declared as weak (and then, only if the composer
/// is enabled).
/// When targeting an interface, indicates a dependency on enabled composers implementing
/// the interface. It could be no composer at all, unless the requirement has explicitly been
/// declared as strong (and at least one composer must be enabled).
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
public sealed class ComposeAfterAttribute : Attribute
{
///
/// Initializes a new instance of the class.
///
/// The type of the required composer.
public ComposeAfterAttribute(Type requiredType)
{
if (typeof(IComposer).IsAssignableFrom(requiredType) == false)
throw new ArgumentException($"Type {requiredType.FullName} is invalid here because it does not implement {typeof(IComposer).FullName}.");
RequiredType = requiredType;
}
///
/// Initializes a new instance of the class.
///
/// The type of the required composer.
/// A value indicating whether the requirement is weak.
public ComposeAfterAttribute(Type requiredType, bool weak)
: this(requiredType)
{
Weak = weak;
}
///
/// Gets the required type.
///
public Type RequiredType { get; }
///
/// Gets a value indicating whether the requirement is weak.
///
/// Returns true if the requirement is weak (requires the other composer if it
/// is enabled), false if the requirement is strong (requires the other composer to be
/// enabled), and null if unspecified, in which case it is strong for classes and weak for
/// interfaces.
public bool? Weak { get; }
}
}