I'm working on a legacy application build with ASP.NET Dynamic Data. The models, as per usual, are all read-only and one can set the display name or description through attributes.
This worked well, however, now I'm in a situation where I need to query two different sources (resource file and some other source) for display name.
The code before was clean, because we only queried the resources:
[Display(ResourceType = typeof(Resources.m_Res), Name = "M_RES_MIMETYPE_ID", Description = "M_RES_MIMETYPE_ID_DESCR")]
This was totally fine and it worked as intended. However, now I have to get the display name and description firstly from some other file and if everything else fails, I have to fallback to resources.
I had to create two different custom attributes, something in this manner:
public class MGADisplayName : DisplayNameAttribute
{
private readonly string propertyName;
public string Name { get; set; }
public Type TableName { get; set; }
public Type ResourceType { get; set; }
public MGADisplayName([CallerMemberName] string PropertyName = null)
{
propertyName = PropertyName;
}
public override string DisplayName
{
get
{
var key = (TableName.Name + ":" + (propertyName ?? Name)).ToLower();
if (/* SOME QUERYING */)
{
return QUERY[key];
}
else
{
string property = Resources.m_Res.ResourceManager.GetString(Name);
if (property != null)
{
return property;
}
else
{
return Name;
}
}
}
}
}
This kind of works and I guess it's OK for the time being, but the next issue is around the corner: I'll need to do with Display.GroupName the same.
Now, as far as I know, there is no GroupNameAttribute to extend, so I'm kind of in the dark here.
I wish I could extend the DisplayAttribute, it would be EXACTLY what I need, but the class is sealed, so that's a dead end.
I wish I could change the model on the fly and provide DisplayName and Description through setters, but the model has only getters, so that's another dead end.
I'm running slowly out of options here. What else can be done here?
Although DisplayAttribute class is sealed, it can be customized via ResourceType property:
Two things to mention. First, it also handles
GroupName. Second is mentioned in the Remarks section:Shortly, the provided type can be any public class / struct having public static string property for each string key.
This perfectly fits with
PublicResXFileCodeGeneratorgenerated typed resource classes. But the important is that it can be arbitrary type, and you can utilize that fact.For instance:
Usage:
Test:
So, this is the solution.
Now, the only problem with it is the need to manually add
stringproperty for each resource key. It could be solved by rolling out your own single file generator or T4 template generator, but how to do that I believe is out of the scope of this post.