Search code examples
c#postsharp

Post sharp using instance member


I am attempting to create an aspect to manage security on a few properties of a class. However, the security aspect for one member relies on the data in another property of the class. I've read some tutorials on the IntroduceAspect, but I'm not sure it's what I need.

public class ClassWithThingsIWantToSecure
{

    [SecurityAspectHere(inherits from LocationInterceptionAspect)]
    public int ThingIWantToSecure;

    public string ThingINeedToKnowAboutInSecurityAspect;
}

Can someone point me in the right direction for making the runtime value of ThingINeedToKnowAboutInSecurityAspect available in the SecurityAspect?


Solution

  • I have done something a bit like this before, I've knocked up a test on a machine with postsharp installed and just tried it out, here is the code...

        class Program
    {
        static void Main(string[] args)
        {
            Baldrick baldrick = new Baldrick();
            baldrick.ThingINeedToKnowAboutInSecurityAspect = "Bob";
            Console.WriteLine("There are {0} beans", baldrick.ThingIWantToSecure);
    
            baldrick.ThingINeedToKnowAboutInSecurityAspect = "Kate";
    
            try
            {
                //This should fail
                Console.WriteLine("There are {0} beans", baldrick.ThingIWantToSecure);
            }
            catch (Exception ex)
            {
                //Expect the message from my invalid operation exception to be written out (Use your own exception if you prefer)
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    
    
    }
    
    [Serializable]
    public class SecurityAspect : LocationInterceptionAspect
    {
        public override void OnGetValue(LocationInterceptionArgs args)
        {
            ISecurityProvider securityProvider = args.Instance as ISecurityProvider;
            if (securityProvider != null && securityProvider.ThingINeedToKnowAboutInSecurityAspect != "Bob")
                throw new InvalidOperationException("Access denied (or a better message would be nice!)");
            base.OnGetValue(args);
        }
    }
    
    
    
    public interface ISecurityProvider
    {
        string ThingINeedToKnowAboutInSecurityAspect { get; }
    }
    
    public class Baldrick : ISecurityProvider
    {
        public string ThingINeedToKnowAboutInSecurityAspect { get; set; }
    
        [SecurityAspect]
        public int ThingIWantToSecure{get { return 3; }}
    }
    

    So, the idea here is to interrogate the args.Instance property for the instace of the object that is being decorated.