SharpCrafters Forum – Metadata (attribute) injection

SharpCrafters Support Forum

        


Metadata (attribute) injection Expand / Collapse
Author
Message
Posted 7/2/2008 2:16:58 PM


Community Member
Just thinking... one very useful feature (that I can't see at the moment) would be the ability to add attributes at compile time. In particular, I'm thinking of generated classes (such as LINQ-to-SQL, LINQ-to-Entities, SOAP, WCF, etc); you can add a partial class with additional methods / class-attributes, but you can't add attributes to existing members. And if you edit the generated code it will get lost next time you rebuild etc.

So (for example) if the user defined a DisplayNameAspect that returns (perhaps) a CustomAttributeBuilder, i.e.

[DisplayNameAspect(Target="Bar", DisplayName="Hello world")]
class Foo {
 public String Bar {get;set;}
}

then this would be as though we had:
class Foo {
 [DisplayName("Hello world")]
 public string Bar {get;set;}
}

Again; the main driver here being partial classes where the member (Bar) is outside of our direct control; and obviously the caller would need to do something to provide the attribute in a convenient way (maybe CustomAttributeBuilder, maybe something else).

Thoughts? Is this already supported?

Marc
Post #3527
Posted 7/2/2008 2:40:58 PM


Gael Fraiteur

SharpCrafters
Good idea.

It is not supported, but would be pretty easy to realize (combined with CompoundAspect).
Post #3528
Posted 7/11/2008 9:48:50 AM


Community Member
Re the "something else", perhaps an easier option would be to clone the attributes from a prototype member (that might perhaps get removed in the process). Now to read up on compound aspect!
Post #3529
Posted 5/12/2009 12:23:13 PM


Colin Jack

Community Member
Good idea.

It is not supported, but would be pretty easy to realize (combined with CompoundAspect).


I was wondering how you would do this using the current version as it is a feature I would find very useful.
Post #3530
Posted 5/12/2009 12:27:33 PM


Gael Fraiteur

SharpCrafters
It is implemented as CustomAttributeInjectorAspect. You have to use a CompoundAspect add add CustomAttributeInjectorAspect whererever you want.

-g
Post #3531
Posted 5/20/2009 10:04:29 AM


Colin Jack

Community Member
Excellent thanks, do you happen to have any examples of using CustomAttributeInjectorAspect as its not immediate obvious to me what to do with it and googling didn't turn up anything much.
Post #3532
Posted 5/20/2009 10:51:31 AM


Gael Fraiteur

SharpCrafters
Here is an aspect that puts an Obsolete custom attributes on all methods:


[MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Struct)]
internal class MyAspect : CompoundAspect
{
   internal const string ObsoleteMessage = "This method is now obsolete.";

   private static readonly ConstructorInfo obsoleteConstructor =
       typeof(ObsoleteAttribute).GetConstructor(new[] { typeof(string) });

   public override void ProvideAspects(object element, LaosReflectionAspectCollection collection)
   {
       Type targetType = (Type)element;

       foreach (MethodInfo method in targetType.GetMethods())
       {
           collection.AddAspect(method, new CustomAttributeInjectorAspect(
                                             new ObjectConstruction(obsoleteConstructor, ObsoleteMessage)));
       }
   }
}
Post #3533
Posted 5/21/2009 10:29:50 AM


Colin Jack

Community Member
Ta, must admit I'm having little luck getting it working, was wondering how you recommend debugging these compound aspects?
Post #3534
Posted 5/21/2009 10:36:41 AM


Gael Fraiteur

SharpCrafters
<!-- m --><a class="postlink" href="http://doc.postsharp.org/1.5/UserGuide/Platform/Debugging.html">http://doc.postsharp.org/1.5/UserGuide/ ... gging.html</a><!-- m -->
Post #3535
Posted 5/21/2009 10:58:36 AM


Colin Jack

Community Member
Actually maybe I should check if what I am trying to do is even possible.

I want to use a Laos (CompoundAspect) attribute which will inject other Laos attributes onto members of the class. I was sure I'd done this in the past but no luck this time, will go look at the samples.

To be honest I'm probably making the mistake of coming back to P# after some time and get up to speed without re-reading the documents.
Post #3536
Posted 5/21/2009 11:06:01 AM


Gael Fraiteur

SharpCrafters
Aaah - this is something else.
Look at the sample PostSharp.Samples.Binding.

Basically, using CompoundAspect, you can add any aspect to any declaration.

-g
Post #3537
Posted 5/21/2009 12:27:51 PM


Colin Jack

Community Member
Ahh ok ta, it was the use of "CustomAttributeInjectorAspect" that was messing it up, it works now thanks! <!-- s:) --> <!-- s:) -->
Post #3538
Posted 5/22/2009 12:47:17 PM


Colin Jack

Community Member
Hi,

Unfortunately the design is scuppering me. I need to copy attributes from one place to another and I don't want to have to write special code to copy particular types of attributes.

Unfortunately ObjectConstruction isn't much use for this because I don't want to have to specify what arguments to pass to the constructor of a new attribute, because I have no idea what constructor to use or what values to copy over. Instead I thus want to clone the attribute, and the way I was planning to do it looks like this:

                   object clone = cloneFactory.Clone(attributeToCopyOver);

                   var attributeAspect = new CustomAttributeInjectorAspect(clone);

                   collection.AddAspect(mappingDefinition.ToProperty, attributeAspect );

This doesn't work with your current design though (or maybe I need to look at other classes which I'll do next), but I definitely think it would be useful.

Ta,

Colin
Post #3539
Posted 5/23/2009 7:07:21 PM


Gael Fraiteur

SharpCrafters
Obviously, when you write an ObjectConstructor, you need to know what constructor has been known. There is no workaround. But you can know this info by requesting a CustomAttributeData. Then you could transform it under an ObjectConstruction. I agree it would be nice if the feature is included in PostSharp.
Post #3540
Posted 5/25/2009 10:43:45 AM


Colin Jack

Community Member
Hi,

I guess what I'm saying is in a future version it would be nice if instead of passing in an ObjectConstruction to CustomAttributeInjectorAspect I could either pass in the attribute to use or I could pass in an IObjectCreator interface with a single method called Create, allowing me to control the attribute creation.

Whether thats workable with PostSharp I don't know, I'll look at the CustomAttributeData idea and see if I can get it to do what I want.

Thanks again,

Colin
Post #3541
Posted 5/25/2009 11:21:55 AM


Gael Fraiteur

SharpCrafters
I guess what I'm saying is in a future version it would be nice if instead of passing in an ObjectConstruction to CustomAttributeInjectorAspect I could either pass in the attribute to use or I could pass in an IObjectCreator interface with a single method called Create


It will surely not be possible to pass a constructed attribute. We really need the information about how to create the attribute (constructor, arguments and named arguments), because this is the way how custom attributes are represented in a .NET assemblies. This is an intrinsic constraint of the MSIL specification and there is no workaround (the constraint makes perfectly sense, also).

-g
Post #3542
Posted 7/22/2009 10:43:06 AM


Colin Jack

Community Member
But you can know this info by requesting a CustomAttributeData. Then you could transform it under an ObjectConstruction. I agree it would be nice if the feature is included in PostSharp.


Wondering if you see this being added in the next version?

We'd find it very useful I think.
Post #3543
Posted 7/22/2009 11:44:52 AM


Gael Fraiteur

SharpCrafters
I forgot about this feature.

You can add a feature request in the issue tracker if you think it should be done.

-gael
Post #3544
Posted 7/22/2009 1:12:08 PM


Colin Jack

Community Member
My fault for not following up, its now reported:

<!-- m --><a class="postlink" href="http://www.postsharp.org/tracker/view.php?id=365">http://www.postsharp.org/tracker/view.php?id=365</a><!-- m -->

Thanks,

Colin
Post #3545
« Prev Topic | Next Topic »


All times are GMT +1:00, Time now is 11:35am

Powered By InstantForum.NET v4.1.4 © 2010
Execution: 0.221. 7 queries. Compression Disabled.