Solved

Passing Delegate into Attribute constructor

Posted on 2004-10-10
6
534 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 250 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
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
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

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

Question has a verified solution.

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

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Suggested Courses

617 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