2009-10-20 6 views
1

Je souhaite implémenter un attribut simple qui est utilisé pour mapper des colonnes de base de données à des propriétés.Comment rendre un Attribut conscient du Nom de la Proprty sur laquelle il se trouve?

Alors ce que j'ai à ce jour est quelque chose qui attaché comme ceci:

[DataField("ID")] 
    public int ID { get; set; } 

    [DataField("Name")] 
    public String Name { get; set; } 

    [DataField("BirD8")] 
    public DateTime BirthDay { get; set; } 

Est-il possible que je puisse faire l'attribut « conscient » du terrain, il est, de sorte que pour les propriétés où le nom est le même que le nom de colonne, je peux simplement appliquer l'attribut sans le paramètre de nom, ou devrais-je traiter de cela au point où je reflète les propriétés. Je veux finir par faire ceci:

[DataField] 
    public int ID { get; set; } 

    [DataField] 
    public String Name { get; set; } 

    [DataField("BirD8")] 
    public DateTime BirthDay { get; set; } 

Répondre

3

L'attribut lui-même ne sera pas au courant de ce qu'il est appliqué, mais le code traitement les attributs est susceptible d'être en cours d'exécution à travers PropertyInfo valeurs etc et trouver la attributs associés à eux. Ce code peut ensuite utiliser à la fois la propriété et l'attribut de manière appropriée.

Pour rendre les choses plus simples, vous pouvez écrire une méthode sur l'attribut pour lui permettre de fusionner ses informations avec les informations de la propriété, de sorte que vous appelleriez:

DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal 
dfa = dfa.MergeWith(propertyInfo); 

Notez que pour la Cela devrait créer une nouvelle instance de l'attribut, plutôt que de changer l'existant. Sinon, vous voudrez peut-être une toute catégorie distincte pour représenter « les informations sur un champ de données »:

DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal 
DataFieldInfo info = dfa.MergeWith(propertyInfo); 

De cette façon, vous pouvez aussi construire DataFieldInfo objets sans référence aux attributs, ce qui pourrait être une bonne séparation conceptuelle - vous permettant de charger facilement la config à partir d'un fichier XML ou quelque chose de similaire si vous le souhaitez.

+1

Il y a juste un problème lorsque vous ne possédez pas le code traitant les attributs. Nous sommes confrontés à ce problème avec les attributs de localisation, cela pourrait aussi être un problème dans les attributs de validation et autres. Nous avons quelques attributs où nous devons passer le nom de la propriété et le type de la classe sur laquelle elle est définie comme argument - ce qui est vraiment mauvais. –

+0

Si vous ne possédez pas le code traitant les attributs, alors il a probablement été conçu en supposant les restrictions que les attributs ont toujours - à savoir que vous ne pouvez pas accéder à la cible. Je suis d'accord que c'est un peu pénible. –

+0

Merci. J'ai réussi à trouver une solution où je reflétais l'attribut. –

1

Si cela ne vous dérange pas d'utiliser postsharp, vous pouvez regarder Here, à une question précédente, j'ai demandé laquelle était proche. J'ai fini par utiliser le temps de compilation valider pour faire ce que je voulais, bien qu'il y ait d'autres options, comme CompileTimeInitalize.

public override void CompileTimeInitialize(object element) 
{ 
    PropertyInfo info = element as PropertyInfo; 

    //.... 
} 
+0

Merci. Je ne pouvais pas utiliser cette approche ici, mais je sais maintenant que postsharp existe et ce qu'il peut faire. Très appréciée. –

Questions connexes