Reputation: 167
I have an assembly that contains service contracts(assembly name is Contracts
). I want to implement authorization on those methods using attributes and PostSharp.
The authorization attribute looks like this:
public class Auth : System.Attribute
{
public Auth(String permission){...}
}
I want my service contracts to look like this:
namespace Contracts
{
public interface IService
{
[Auth("CanCallFoo")]
void Foo();
}
}
I want to check at compile-time that all the methods from the interfaces in the Contracts
assembly have an Auth
attribute.
In order to do this I've created the following aspect:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Interface & MulticastTargets.Method)]
public class EnforceSecurityAspect : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(System.Reflection.MethodBase method)
{
var hasSecurityAttribute = method.GetCustomAttributes(true).Any(x => x is Auth);
if (!hasSecurityAttribute)
{
throw new InvalidAnnotationException(String.Format("Add `Auth` to `{0}`", method.Name));
}
return base.CompileTimeValidate(method);
}
}
I apply the aspect using this line of code in AssemblyInfo of Contracts
assembly:
[assembly: EnforceSecurityAspect()]
Within the same assembly I also have DTOs, which are used by the services.
The problem I am facing is that the aspect gets also applied to DTOs
For example I have a DTO like this
public class Client
{
public String Name{get;set;}
}
and at compile-time i get an error that says that I should add Auth
to the compiler-generated get_Name
method.
Q: Is there a way to tell Postsharp that the aspect should be applied only to methods of interfaces?
Upvotes: 1
Views: 896
Reputation: 381
I know this is an old question but I wanted to provide an anwser to anyone having this issue as well.
While it may be possible to use specific targets inheriting/implementing a certain interface/class with postsharp i dont't know how.
the solution to this is to create an aspect and target the classes (haven't dont this yet, but im sure its possible). you can then use reflection to validate only the classes that inherit from a certain class/interface using methods available on Type such as FindInterfaces
use something simmilat to the below code. (Note this is a postsharp Enterprice feature)
[MulticastAttributeUsage(MulticastTargets.Class)]
public class MulticastTest : MulticastAttribute, IScalarConstraint
{
public void ValidateCode(object target)
{
throw new NotImplementedException();
}
public bool ValidateConstraint(object target)
{
var type = target.GetType();
Console.Write(type.Name);//Actually do something here
return true;
}
}
Upvotes: 1