Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Passing Delegate into Attribute constructor

Posted on 2004-10-10
6
Medium Priority
?
539 Views
Last Modified: 2013-11-19
I want to do something like the following:

public delegate void EmptyDelegate();

public class MyAttAttribute : Attribute
{
public MyAttAttribute(EmptyDelegate Del)
{
...
}
}

[MyAtt(new EmptyDelegate(Foo.DoNothing))]
public class Foo
{
public static void DoNothing()
{
...
}
}

However, when I compile, I'm told that Attribute constructors must take only constants.  Is there anyway to pass a Delegate into an Attribute constructor?

In the meantime, my workaround has been to add the following MyAttAttribute constructor:

public MyAttAttribute(Type ClassType, string DelegateName) : this((EmptyDelegate)EmptyDelegate.CreateDelegate(typeof(EmptyDelegate), ClassType, DelegateName)) { }

However, this is incredibly lame.
0
Comment
Question by:a_goat
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 6

Accepted Solution

by:
etmendz earned 1000 total points
ID: 12275117
An incredibly lame approach that simply works. I think calls to attributes are resolved at compile-time which explains why you need to pass constants. However, the instance of the attribute is defined at run-time which you may access using Attribute.GetCustomAttributes() and/or reflections.

Try to work around this limitation rather than against it. Attributes are not meant to be very dynamic. As the name implies, Attributes are meant to be declarative, definitive and informative rather than intentionally functional. Most of the time, you'll use attributes to trigger external functionalities instead.

The amount of information you expose through attributes enables services to be invented that consume these information...

Have fun.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12275540
The basic idea of what I'm trying to do is build an engine that processes incoming byte[]s from a socket.  I get a 4 byte header consisting of MessageType and Size.  From the MessageType, I can determine what kind of object this is.  I don't want to have a central factory though.  So the idea I had was that each class has attributes which track what MessageTypes it can handle, and a delegate for each.  That way I can maintain a list of MessageTypes and the accompanying delegate and easily create objects.

Kinda like a modular factory model, where you just need to put a new piece of equipment on the floor and it starts churning stuff out.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12275550
As an aside, is there a way in the attribute's code to discover what class it is associated with (assuming it is associated with a class).

That actually brings up a good idea.  I could potentially put these attributes on methods instead of the class.  It would mean more crawling though.  Ugh
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 6

Expert Comment

by:etmendz
ID: 12283587
Interesting... let me see...

* Dynamic *
Add attributes to your classes in order to define their purpose passing only types and strings and stuffs as you are doing now. Keep the constructor simple storing the passed parameters as properties of the attribute instance at run-time.

Then create a separate class which uses reflections to get information about your classes and their attributes and then store the inventory to a collection or XML. The structure should map classes or methods against message types and delegates for example. Use this inventory to instantiate objects.

* Static *
Maintain the inventory of classes, methods mapped to message types and delegates in an XML or configuration file and let a separate class load them at run-time. No need for attributes but should work the same.

See which one would work best for you. I think the * Static * would load and initialize faster, though... Here's a tip, read about attributes used for AOP and instrumentation in .Net. You might find something useful...

http://msdn.microsoft.com/msdnmag/issues/02/03/aop/
http://msdn.microsoft.com/msdnmag/issues/04/04/InstrumentationinNET/default.aspx
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=572
http://www.dotnetguru.org/us/modules.php?op=modload&name=News&file=index&catid=&topic=16
You can also search in Google for "AOP in .Net" or "Instrumentation in .Net" for more information...

Have fun.
0
 
LVL 3

Author Comment

by:a_goat
ID: 12286049
So what I've got now is the dynamic version, which is what I want.  Static has too much danger of some noob coming in and jacking it all up (always a concern at my job).  

There are 2 flaws with what I'm doing though:

1.) The developer has to be careful to put the correct type in the attribute's constructor.  i.e.

[MyAtt(typeof(Foo), "DoNothing")]
public class Foo
{
public static void DoNothing()
{
...
}
}

Because the class is unnecessarily copied, that can lead to problems

2.) The developer can deliberately put the wrong type in the constructor.  This just leads to some of the worst spagetti code imaginable.  i.e.

[MyAtt(typeof(Bar), "DoNothingBar")]
public class Foo
{
public static void DoNothingFoo()
{
...
}
}

[MyAtt(typeof(Foo), "DoNothingFoo")]
public class Bar
{
public static void DoNothingBar()
{
...
}
}

Here Bar and Foo's attributes are cross-matched.  

Both these problems would be solved if the attribute knew what class it was associated with.  Is there any way to discover that?
0
 
LVL 6

Expert Comment

by:etmendz
ID: 12294402
Looks like it is not possible... Use reflections to collect the inventory of members... You can use attributes to identify which members to include in your inventory... Then use another class to map the inventory to your collection of rules...

Have fun...
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question