tags:

views:

51

answers:

2

I have created an Attribute, call MyAttribute, which is performing some security and for some reason the Constructor is not being fired, any reason why?

public class Driver
{
    // Entry point of the program
    public static void Main(string[] Args)
    {
        Console.WriteLine(SayHello1("Hello to Me 1"));
        Console.WriteLine(SayHello2("Hello to Me 2"));

        Console.ReadLine();
    }

    [MyAttribute("hello")]
    public static string SayHello1(string str)
    {
        return str;
    }

    [MyAttribute("Wrong Key, should fail")]
    public static string SayHello2(string str)
    {
        return str;
    }


}

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{

    public MyAttribute(string VRegKey)
    {
        if (VRegKey == "hello")
        {
            Console.WriteLine("Aha! You're Registered");
        }
        else
        {
            throw new Exception("Oho! You're not Registered");
        };
    }
}
+6  A: 

Attributes are applied at compile time, and the constructors used only to fill in the properties. Attributes are metadata, and can only be examined at runtime.

In fact, Attributes should not contain any behavior at all.

Dave Van den Eynde
If this is the case, how else can set the security of a method?
Coppermill
That's a completely different topic, but you might want to take a look at Code Access Security.
Dave Van den Eynde
I wouldn't recommend CAS as it is very complex to get right and has been deprecated in .Net 4.0.
adrianbanks
CAS policy has been deprecated. That doesn't mean that the whole of CAS has been deprecated.
Dave Van den Eynde
A: 

Actually it fails, but only if you are trying to get attribute properties. Here is an example that fails:

using System;

public class Driver
{
// Entry point of the program
    public static void Main(string[] Args)
    {
        Console.WriteLine(SayHello1("Hello to Me 1"));
        Console.WriteLine(SayHello2("Hello to Me 2"));

        Func<string, string> action1 = SayHello1;
        Func<string, string> action2 = SayHello2;

        MyAttribute myAttribute1 = (MyAttribute)Attribute.GetCustomAttribute(action1.Method, typeof(MyAttribute));
        MyAttribute myAttribute2 = (MyAttribute)Attribute.GetCustomAttribute(action2.Method, typeof(MyAttribute));

        Console.ReadLine();
    }

    [MyAttribute("hello")]
    public static string SayHello1(string str)
    {
        return str;
    }

    [MyAttribute("Wrong Key, should fail")]
    public static string SayHello2(string str)
    {
        return str;
    }


}

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{

    public string MyProperty
    {
        get; set;
    }

    public string MyProperty2
    {
        get;
        set;
    }

    public MyAttribute(string VRegKey)
    {
        MyProperty = VRegKey;
        if (VRegKey == "hello")
        {
            Console.WriteLine("Aha! You're Registered");
        }
        else
        {
            throw new Exception("Oho! You're not Registered");
        };

        MyProperty2 = VRegKey;
    }
}
Andrew Bezzub
So now you can get your code to throw an exception. But does that prevent you from calling the method itself?
Dave Van den Eynde
I agree that it is wrong to have any behaviour in the Attributes. But the question was why exception does not happen in the above code and the answer is - because instance of the attribute class is created when you trying to access it.
Andrew Bezzub