2010-07-27 11 views
2

J'essaye d'écrire un DisplayNameAttribute fortement typé et localisable, mais je n'arrive pas à le compiler. Ce que je voudrais faire mes propriétés ViewModel est quelque chose commeUn DisplayNameAttribute fortement typé et localisable

[LocalizedDisplayName<HomeResources>(r => r.WelcomeMessage)] 

qui en fait la même chose que

[DisplayName("Welcome to my site!")] 

sauf le message est localisé. Cependant, je ne peux pas obtenir le fonctionnement du constructeur générique (comment fournir des arguments de type à un constructeur?) Ni le choix de la chaîne à utiliser. Le constructeur actuel ressemble à ce

public class LocalizedDisplayNameAttribute<TResource> : DisplayNameAttribute 
{ 
    public LocalizedDisplayName(Expression<Func<TResource, string>> resource) 
    { // ... 

mais le compilateur se plaint que l'argument d'entrée est un temps de compilation constante, donc apparemment cette façon de le faire est pas valide.

Existe-t-il un moyen d'obtenir un attribut localisé fortement typé pour le nom d'affichage? Y en a-t-il déjà un là-bas?

Répondre

0

Les classes d'attributs ne peuvent pas être génériques.

+0

OK. Savez-vous s'il existe une autre façon de rendre l'attribut de nom d'affichage fortement typé? –

0

OMI, la seule façon que vous pouvez faire est la suivante:

[LocalizedDisplayName("WelcomeMessage")] 

En fait les attributs cadres ne sont pas typés (comme DefaultPropertyAttribute etc)

0

Comme un attribut ne peut pas être générique et ses arguments doivent soyez constants, vous ne pouvez pas le faire comme vous le décrivez. Quoi qu'il en soit, les membres des classes de ressources générées par le concepteur sont statiques, vous ne pouvez donc pas y accéder via une instance.

Une autre option serait de ne laisser passer que le nom de la ressource à l'attribut:

[DisplayNameResourceKey("WelcomeMessage")] 

Lorsque vous souhaitez récupérer le message réel, il vous suffit d'appeler ResourceManager.GetString avec la clé des ressources. Mais bien sûr, vous perdez le typage fort ...

3

Vous ne pouvez pas le faire via un attribut. Gardez à l'esprit qu'un attribut est purement métadonnées incorporées dans un assembly. Il n'existe actuellement aucun moyen d'incorporer une construction de code telle qu'une expression en tant que métadonnées.

Si vous vouliez vraiment fournir un moyen de spécifier ces métadonnées d'une manière fortement typée, vous pouvez écrire votre propre ModelMetadataProvider. C'est une tâche assez avancée, mais je suis actuellement au milieu d'un article de blog qui montre comment en écrire un que je posterai bientôt avec espoir.

+1

Salut Phil! =) Des nouvelles sur ce blog? –

+0

@TomasLycken, http://haacked.com/archive/2011/07/14/model-metadata-and-validation-localization-using-conventions.aspx – smartcaveman