Je tente de générer un nouvel ensemble d'interfaces wcf basé sur des interfaces existantes. J'utilise l'espace de noms Reflection.Emit pour accomplir ceci. Mon problème est de savoir comment copier les anciens attributs personnalisés d'une méthode à la nouvelle méthode. Chaque exemple que j'ai vu de SetCustomAttributes() nécessite de connaître au préalable le type d'attribut. J'ai besoin de découvrir le type d'attribut lors de l'exécution. Des pensées?Utilisation de Reflection.Emit pour copier un attribut personnalisé dans une autre méthode
4
A
Répondre
0
essayez ceci:
MethodInfo mi;
//...
object[] custAttribs = mi.GetCustomAttributes(false);
foreach (object attrib in custAttribs)
attrib.GetType();
Je suppose que vous avez MethodInfo pour vos méthodes
2
Voici la réponse que je suis venu avec après quelques recherches.
CustomAttributeBuilder ct = AddAttributesToMemberInfo(methodInfo);
if (ct != null)
{
methodBuilder.SetCustomAttribute(ct);
}
CustomAttributeBuilder AddAttributesToMemberInfo(MemberInfo oldMember)
{
CustomAttributeBuilder ct = null;
IList<CustomAttributeData> customMethodAttributes = CustomAttributeData.GetCustomAttributes(oldMember);
foreach (CustomAttributeData att in customMethodAttributes)
{
List<object> namedFieldValues = new List<object>();
List<FieldInfo> fields = new List<FieldInfo>();
List<object> constructorArguments = new List<object>();
foreach (CustomAttributeTypedArgument cata in att.ConstructorArguments)
{
constructorArguments.Add(cata.Value);
}
if (att.NamedArguments.Count > 0)
{
FieldInfo[] possibleFields = att.GetType().GetFields();
foreach (CustomAttributeNamedArgument cana in att.NamedArguments)
{
for (int x = 0; x < possibleFields.Length; x++)
{
if (possibleFields[x].Name.CompareTo(cana.MemberInfo.Name) == 0)
{
fields.Add(possibleFields[x]);
namedFieldValues.Add(cana.TypedValue.Value);
}
}
}
}
if (namedFieldValues.Count > 0)
{
ct = new CustomAttributeBuilder(att.Constructor, constructorArguments.ToArray(), fields.ToArray(), namedFieldValues.ToArray());
}
else
{
ct = new CustomAttributeBuilder(att.Constructor, constructorArguments.ToArray());
}
}
return ct;
}
5
La réponse que vous (frjames) est proche au courant, mais ne tient pas compte initializers de propriété comme ...
[ServiceBehavior(Name="ServiceName")]
Cependant, l'idée de convertir CustomAttributeData à un CustomAttributeBuilder pour une utilisation dans la réflexion .Emit est juste sur.
J'ai fini par le faire pour un projet open source (Autofac) et est venu avec cette méthode d'extension:
public static CustomAttributeBuilder ToAttributeBuilder(this CustomAttributeData data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var constructorArguments = new List<object>();
foreach (var ctorArg in data.ConstructorArguments)
{
constructorArguments.Add(ctorArg.Value);
}
var propertyArguments = new List<PropertyInfo>();
var propertyArgumentValues = new List<object>();
var fieldArguments = new List<FieldInfo>();
var fieldArgumentValues = new List<object>();
foreach (var namedArg in data.NamedArguments)
{
var fi = namedArg.MemberInfo as FieldInfo;
var pi = namedArg.MemberInfo as PropertyInfo;
if (fi != null)
{
fieldArguments.Add(fi);
fieldArgumentValues.Add(namedArg.TypedValue.Value);
}
else if (pi != null)
{
propertyArguments.Add(pi);
propertyArgumentValues.Add(namedArg.TypedValue.Value);
}
}
return new CustomAttributeBuilder(
data.Constructor,
constructorArguments.ToArray(),
propertyArguments.ToArray(),
propertyArgumentValues.ToArray(),
fieldArguments.ToArray(),
fieldArgumentValues.ToArray());
}
Que l'on tient compte de toutes les façons d'initialiser l'attribut.
1
Le code de Travis Illig doit être modifié comme ci-dessous pour travailler avec .Net de base:
foreach (var namedArg in data.NamedArguments)
{
string argName = namedArg.MemberName;
var fi = data.AttributeType.GetField(argName);
var pi = data.AttributeType.GetProperty(argName);
Questions connexes
- 1. Utilisation de Reflection.Emit de .NET pour générer une interface
- 2. Un attribut personnalisé .NET pour effectuer une usurpation d'identité?
- 3. Un autre IKImageView Question: copier une région
- 4. .NET: clonage dynamique d'une méthode existante avec Reflection.Emit
- 5. Attribut personnalisé dans ASP.NET pour Page_Load
- 6. Reflection.Emit Generic Base Class Méthode générique Appelez
- 7. Attribut personnalisé pour assurer l'encapsulation
- 8. Attribut de conception personnalisé pour WPF
- 9. Comment récupérer un attribut personnalisé dans watir?
- 10. Comment puis-je transmettre une méthode d'exécution à un attribut personnalisé ou une approche alternative viable
- 11. java IO pour copier un fichier vers un autre
- 12. Accès attribut de méthode enveloppé dans C#
- 13. jQuery Attribut Utilisation pour cible
- 14. Copier un CharArrayBuffer dans un autre CharArrayBuffer
- 15. Méthode native pour copier tous les nœuds enfants dans un autre élément
- 16. Cadre pour .net Reflection.Emit simplification?
- 17. jQuery attribut sélecteurs: Comment interroger pour un attribut avec un espace de noms personnalisé
- 18. Attribut personnalisé .NET WebService
- 19. copier une partie d'un tableau dans un autre tableau
- 20. Passage d'une méthode à une autre méthode
- 21. Existe-t-il une méthode pour copier une nouvelle colonne dans une table existante et copier les informations de colonne d'une autre table dans Oracle?
- 22. comment copier la valeur d'attribut dans un nouvel attribut
- 23. Ajouter un attribut personnalisé avec magento magasin
- 24. L'utilisation de Reflection.Emit pour émettre un bloc "using (x) {...}"?
- 25. Structure Copier vers un autre programme
- 26. C# XML - Copier un attribut à un élément enfant
- 27. Un attribut personnalisé peut-il impliquer d'autres attributs sans héritage?
- 28. Attribut personnalisé dans .NET pour exécuter du code avant et après la méthode décorée?
- 29. Java Équivalent de Reflection.Emit
- 30. Javascript pour ajouter un attribut personnalisé à certains éléments
Je sais que c'est vieux, mais cela est une excellente réponse et m'a sauvé un tas de temps récemment mais je n'ai rencontré un petit problème avec cela aussi. Si vous avez un attribut qui a un argument 'params SomeType [] constructor' (je ne suis pas sûr si les params font une différence ou pas) alors cela échoue parce que pour une raison quelconque la valeur de l'argument constructeur est maintenue comme ReadOnlyCollection' qui ne peut pas être converti en 'SomeType []' par le constructeur CustomAttributeBuilder. –
rcarrington
Ne fonctionne pas dans .Net Core ''CustomAttributeNamedArgument' ne contient pas de définition pour 'MemberInfo'' –
La question/réponse ici a six ans maintenant et est pour le .NET complet. La réflexion du noyau .NET est très différente. –