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