Benutzer mit den meisten Antworten
Custom Attribut aus Extension Methode lesen

Frage
-
Hallo Forum,
ich habe eine Extension Class mit statischen Methoden für die ich Custom Attribute definiert haben.
Ausser den statischen Methoden in der Extension Class kann ich alle Member lesen.
Wie bekomme ich es nun hin per Reflection auch die Custom Attribute der statischen Klasse zu lesen.Danke und Gruß
Gerhard Ahrens
Antworten
-
Hallo Gerhard,
bei deinem Code steigt der bereits weit vor der Ermittlung der Methoden aus (und dabei ist es egal, ob ich das Attribut auf einer Instanz- oder einer statischen Methode anwende). Daher denke ich mal, dass das Problem mit deinem Code nichts mit statisch oder nicht statisch zu tun hat.
if( type.IsPublic == true && type.GetCustomAttributes( typeof( TValue ), true ).Length > 0 )
sorgt (zumindest in meiner Testanwendung) dafür, dass die Schleife aussteigt, da es keine Klasse gibt, die das LibraryDoc Attribut verwendet. In deinem Fall ist das wohl genauso.
Zudem rufst Du die identische Methode zweimal auf, was letztendlich eine schlechtere Performance zur Folge hat.
Einmal eben:
if( type.IsPublic == true && type.GetCustomAttributes( typeof( TValue ), true ).Length > 0 )
und direkt dahinter nochmal:
dynamic attr = type.GetCustomAttributes( typeof( TValue ), true )
Macht natürlich wenig Sinn.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert Gerhard Ahrens Donnerstag, 27. Juli 2017 08:57
Alle Antworten
-
Hallo Gerhard,
poste bitte den Code, mit dem Du die Attribute für die normalen Methoden ausliest.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Stefan,
das ist, denke ich der relevante Teil. Ich will alle Attribute vom Typ "LibraryDocAttribute" in eine Liste packen. Wie geschrieben, klappt das bei allen Member, nur bei den aus einer Extension Klasse nicht. Mit den BindungsFlags habe ich auch verschiedene Varianten probiert.
private List<TValue> GetClassAttribute<TValue>(Assembly assembly) where TValue : Attribute { List<TValue> attrList = new List<TValue>(); BindingFlags bindingFlags = BindingFlags.Static
| BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.FlattenHierarchy; foreach (Type type in assembly.GetTypes().AsParallel()) { if (type.IsPublic == true &&
type.GetCustomAttributes(typeof(TValue), true).Length > 0) { dynamic attr = type.GetCustomAttributes(typeof(TValue), true)
.Cast<TValue>()
.FirstOrDefault<TValue>(); if (attr == null) { continue; } attr.Namespace = type.Namespace; attr.MemberName = type.Name; attrList.Add(attr as TValue); PropertyInfo[] properties = type.GetProperties(bindingFlags); foreach (var property in properties.AsParallel()) { object[] attributes = property.GetCustomAttributes(typeof(TValue), true); foreach (var attribute in attributes.AsParallel()) { if (attribute.GetType() == typeof(TValue)) { dynamic attrMember = attribute; attrMember.Namespace = type.Namespace; attrMember.ClassName = type.Name; attrMember.MemberName = property.Name; attrMember.MemberTyp = property.MemberType.ToString(); attrMember.ReturnTyp = property.PropertyType.Name; attrList.Add(attrMember as TValue); } } } MethodInfo[] methodes = type.GetMethods(bindingFlags); foreach (var methode in methodes.AsParallel()) { object[] attributes = methode.GetCustomAttributes(typeof(TValue), true); foreach (var attribute in attributes.AsParallel()) { if (attribute.GetType() == typeof(TValue)) { dynamic attrMember = attribute; attrMember.Namespace = type.Namespace; attrMember.ClassName = type.Name; attrMember.MemberName = methode.Name; attrMember.MemberTyp = methode.MemberType.ToString(); attrMember.ReturnTyp = methode.ReturnParameter.ToString(); attrMember.IsStatic = methode.IsStatic; attrMember.Parameters = this.ParameterToString(methode.GetParameters()); attrList.Add(attrMember as TValue); } } } } } return attrList; }
- Bearbeitet Gerhard Ahrens Donnerstag, 27. Juli 2017 06:44
-
Hi Gerhard,
hast Du auch BindingsFlags.Static gesetzt?--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
Hi Gerhard,
Static ist aber keine Instance.--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
Hallo Peter,
die BindingsFlags ändern nichts am Ergebnis. Die Attribute aus der statischen Klasse bekomme ich nicht zu sehen.
Eventuell macht die Kombination "public static class" und "public static Methode" in Reflection ein Problem. Ich könne mir auch auch nicht erklären warum.
Gruß
Gerhard -
Hallo Gerhard,
ich verstehe den Sinn eines Teils deines Codes nicht, daher habe ich mal eine rudimentäre Methode erstellt, um die CustomAttributes der Methoden (auch statischer Methoden) auszulesen.
private List<TValue> GetCustomAttributes<TValue>( Assembly assembly ) where TValue : Attribute { List<TValue> attrList = new List<TValue>(); BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; foreach( Type type in assembly.GetTypes().AsParallel() ) { MethodInfo[] methods = type.GetMethods( bindingFlags ); foreach ( var method in methods.AsParallel() ) { object[] attributes = method.GetCustomAttributes( typeof( TValue ), true ); foreach (var attribute in attributes.AsParallel() ) { if( attribute.GetType() == typeof( TValue ) ) { attrList.Add( attribute as TValue ); } } } } return attrList; }
Die Klasse für das LibraryDocAttribute sieht dabei so aus:
using System; [AttributeUsage( AttributeTargets.Method, AllowMultiple = false )] public class LibraryDocAttribute : Attribute { public string Key { get; set; } public LibraryDocAttribute( string key ) { this.Key = key; } }
Der Aufruf zur Ermittlung der List<LibraryDoc> dann so:
List<LibraryDocAttribute> attributes = this.GetCustomAttributes<LibraryDocAttribute>( this.GetType().Assembly );
Die Erweiterungsmethode hat folgenden Aufbau:
using System; namespace MeinNamespace { public static class Extensions { [LibraryDoc( "Hallo Welt" )] public static String MakeSomething( this String value ) { return value; } } }
Damit erhalte ich dann beim Aufruf genau ein Element in der attributes Liste mit dem entsprechenden Key.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Gerhard,
bei deinem Code steigt der bereits weit vor der Ermittlung der Methoden aus (und dabei ist es egal, ob ich das Attribut auf einer Instanz- oder einer statischen Methode anwende). Daher denke ich mal, dass das Problem mit deinem Code nichts mit statisch oder nicht statisch zu tun hat.
if( type.IsPublic == true && type.GetCustomAttributes( typeof( TValue ), true ).Length > 0 )
sorgt (zumindest in meiner Testanwendung) dafür, dass die Schleife aussteigt, da es keine Klasse gibt, die das LibraryDoc Attribut verwendet. In deinem Fall ist das wohl genauso.
Zudem rufst Du die identische Methode zweimal auf, was letztendlich eine schlechtere Performance zur Folge hat.
Einmal eben:
if( type.IsPublic == true && type.GetCustomAttributes( typeof( TValue ), true ).Length > 0 )
und direkt dahinter nochmal:
dynamic attr = type.GetCustomAttributes( typeof( TValue ), true )
Macht natürlich wenig Sinn.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert Gerhard Ahrens Donnerstag, 27. Juli 2017 08:57
-