PostSharp.Samples / PostSharp.Samples.Authorization / Framework / RequiresPermissionBaseAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Extensibility;
namespace PostSharp.Samples.Authorization.Framework
  /// <summary>
  ///   Base class for <see cref="RequiresPermissionAttribute" />. This abstraction does not make any assumption regarding
  ///   the implementation of the <see cref="IPermission" />, i.e. it does not assume that a permission is simply a named
  ///   object.
  ///   It could be used to implementation for instance parametric permissions.
  /// </summary>
  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true)]
  public abstract class RequiresPermissionBaseAttribute : Attribute, IPermissionFactory, IAspectProvider
    /// <summary>
    ///   Invoked at build time to get the list of aspects required to implement the current custom attribute.
    /// </summary>
    /// <param name="targetElement">Declaration on which the attribute has been applied.</param>
    /// <returns>A collection of aspect instances.</returns>
    public virtual IEnumerable<AspectInstance> ProvideAspects(object targetElement)
      var aspectRepositoryService =
      var aspects = aspectRepositoryService.GetAspectInstances(targetElement) ?? new IAspectInstance[0];
      var aspect = (AuthorizationAspect) aspects.Select(i => i.Aspect).SingleOrDefault(i => i is AuthorizationAspect);
      if (aspect == null)
        if (targetElement is MethodBase)
          aspect = new MethodAuthorizationAspect();
        else if (targetElement is PropertyInfo || targetElement is FieldInfo)
          aspect = new LocationAuthorizationAspect();
        else if (targetElement is ParameterInfo)
          aspect = new MethodAuthorizationAspect();
          throw new Exception($"Unexpected aspect target: {targetElement.GetType().Name}");
        yield return new AspectInstance(targetElement, aspect);
      var parameterIndex = 0;
      if (targetElement is ParameterInfo parameterInfo)
        parameterIndex = parameterInfo.Position + 1;
      aspect.AddPermission(parameterIndex, this);
    /// <inheritdoc />
    public abstract IPermission CreatePermission(OperationSemantic semantic);