views:

77

answers:

4

I'm trying to write a strongly typed, localizable DisplayNameAttribute, but I can't get it to even compile. What I'd like to do on my viewmodel properties is something like

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

which would basically do the same thing as

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

except the message is localized. However, I can't get neither the generic constructor working (how do you supply type arguments to a constructor?) nor the choosing of what string to use. The current constructor looks like this

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

but the compiler complains that the input argument is not a compile time constant, so apparently this way of doing it is not valid.

Is there any way to get a strongly typed, localized attribute for display name? Is there one out there already?

A: 

Attribute classes cannot be generic.

Darin Dimitrov
OK. Do you know if there is another way to make the display name attribute strongly typed?
Tomas Lycken
A: 

IMO, the only way you can do that is:

[LocalizedDisplayName("WelcomeMessage")]

In fact framework attributes are not typed (like DefaultPropertyAttribute etc)

onof
A: 

Since an attribute can't be generic and its arguments must be constants, you can't do it the way you describe. Anyway, members of the resource classes generated by the designer are static, so you can't access them through a instance.

Another option would be to pass only the name of the resource to the attribute :

[DisplayNameResourceKey("WelcomeMessage")]

When you want to retrieve the actual message, you just call ResourceManager.GetString with the resource key. But of course you lose the strong typing...

Thomas Levesque
+1  A: 

You can't do it via an attribute. Keep in mind that an attribute is purely metadata embedded in an assembly. There's currently no way to embed a code construct such as an expression as metadata.

If you really really wanted to provide a means of specifying this metadata in a strongly typed way, you could write your own ModelMetadataProvider. It's a pretty advanced task, but I'm currently in the middle of a blog post that shows how to write one which I'll post soon hopefully.

Haacked
Hi Phil! =) Any news on that blog post?
Tomas Lycken