Run an Attribute constructor

Asked

Viewed 159 times

3

How do I call the constructor of an attribute before the constructor of the decorated class?

For example, I have my attribute:

using System;    
namespace T.WinForm
{
    public class TesteAttribute : Attribute
    {
        public TesteAttribute()
        {
               Console.WriteLine("Executei o construtor do atributo..."); 
        }
    }
}

And I have the class decorated by the previous attribute:

using System;
namespace SimT.WinForm
{
    public partial class FrmMenuPrincipal : SimTForm
    {
        [TesteAttribute]
        public FrmMenuPrincipal()
        {
            InitializeComponent();
            Console.WriteLine("Executei o construtor da classe...");
        }
    }
}

I wish that when executing this code, the sequence of the console writing would stay that way:

  1. I ran the attribute constructor...
  2. I ran the class builder...

The intention is to do something similar to the AuthorizeAttribute of ASP.Net MVC.

I am trying to do this using a Winforms application with . Net 4.5

1 answer

3


Understand how this decorator works.

To call all attributes of all methods it is necessary to have a code somewhere that attributes are "called". This is done through reflection that will read the metadata existing. Implementation can be done in several ways.

A simple way for this case is to have a method that is invoked in the SimTForm or a base class above it, meaning it has to be manual, but it doesn’t have to be manual everywhere it uses, it can encapsulate the execution in a base class that will always be used and abstract several things, among them the call of attributes. Thus simple inheritance "automates" the execution of attribute constructs.

It is not a good idea to call the constructor directly, because this will completely lose the usefulness of the attribute. If you explicitly call the constructor you don’t need anything else to decorate the method.

Then the base class should "list" all the methods that are of interest to you (you can filter them in various ways, read the documentation and use creativity) and invoke their attributes.

Code that takes the methods of the current class:

this.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance)

Documentation of GetMethods().

To call the attributes:

method.GetCustomAttributes(true);

Documentation of GetCustomAttributes().

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

You obviously need to adapt to your needs. Remembering that there are other ways to get the same result and maybe some of them will be more appropriate.

  • I understand this solution. But now we have a new problem: Who should get the attributes of the class? According to the OP is the class itself. This means that the class has enough information to instantiate the necessary attribute. Usually attributes are for consumption by other libraries, or by the. NET library itself (for example Serializable). So I understand this solution, I realize until it can be used, but I don’t think it’s the best one for this case.

  • It could be, he could use something external, he could get Winforms to work on it, but I can’t imagine if it’s simple or complex to do. This way, it’s simple. Ideally, Winforms already did it. In a way, this base class of it is an extension of Winforms. If it’s the best for him, I can’t say since I don’t know his whole situation.The attributes should be consumed. Who does this doesn’t matter to them. It matters to who’s using them. In this case I tried, as far as possible, to simulate the result he gets in ASP.Net MVC that already knows what to do with the attribute he spoke about.

  • Yeah, and that’s exactly the dust I didn’t want hidden in your answer. Consuming attributes that are declared by the application itself usually takes a lot of work and can involve many other operations with reflection.

  • 1

    Oh yes, it needs to build or extend the functionalities of a framework. Attributes are for the best in these cases.

  • 1

    Hello gentlemen. I tried to dispel my doubt and ended up generating a very interesting discussion where I learned a lot. However what I was looking for was perfectly this solution, because my idea is, as you pointed out, to consume other libraries without me having to leave exposed in the class.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.