using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Chernobyl.Attribution; using Chernobyl.Collections.Generic.Event; using Chernobyl.Values; using Chernobyl.Reflection; namespace Chernobyl.Dependency { /// /// Interface for attributes which get the value of an attributable item. /// public interface IGetAttribute { /// /// Returns the value of the specified attribute provider. The attribute /// provider must be the instance that this /// was attributing. /// /// The instance this /// was /// attributing. /// The value of the requested item. IValue Get(ICustomAttributeProvider attributeProvider); } /// /// Interface for attributes which get the value of an attributable item. /// /// The type being attributed. public interface IGetAttribute : IGetAttribute where TCustomAttributeProvider : ICustomAttributeProvider { /// /// Returns the value of the specified attribute provider. The attribute /// provider must be the instance that this /// was attributing. /// /// The instance this /// was /// attributing. /// The value of the requested item. IValue Get(TCustomAttributeProvider attributeProvider); } /// /// Extensions and utilities for and related types. /// public static class GetAttributeExtensions { /// /// Retrieves the values from the provided /// instances using the /// on each /// to retrieve the value. /// /// The type that can be /// attributed. /// The instances to pull the values from. /// The list of values pulled from . public static IEnumerable> Get(this IEnumerable providers) where TCustomAttributeProvider : ICustomAttributeProvider { // Go through all of the parameters on the method, grab the // IGetAttribute for each, and get the IValue parameter from each. return from parameterInfo in providers let getAttribute = parameterInfo.GetCustomAttributes(true).First() select getAttribute.Get(parameterInfo); } /// /// Returns an that holds the value of return /// parameter on a static method. /// /// The instance that represents the return /// parameter. This instance's must be /// a static . The static method's input parameters /// must be attributed with . /// The instance that holds the return value. /// Thrown when the /// instance's /// is not a . /// Thrown when the /// instance's /// is not static. public static IValue ToReturnValue(this ParameterInfo returnParameter) { MethodBase method = returnParameter.Member.Require(); method.ThrowWhenStaticIs(false); // Create the IValue that will create the instance from the method. var parameters = method.GetParameters().Get().ToEventList(); return new ReturnValue(method, parameters); } } }