Forum: Multi-Language Add-In for Visual Studio

Feature request : Helper for localizing custom attributes

I'm using The addin for a long time now and it keeps improving with each new version (that are quite numerous (!). That is really a very usefull tool.

For me, what is still missing is a way to facilitate localization of custom attribute. For example, I need to have localizable versions of DescriptionAttribute, DisplayNameAttribute, CategoryAttribute, and some others.
I found a way to achieve that by calling ResourceManager by hand in my custom attribute classes and filling resources by hand too. That could easily be improved by using your addin to detect the use of localizable custom attributes in the code and handle localization of all localizable fields of these custom attribute (marked with LocalizableAttribute).
To identify attributes that need localization, you could create an interface that has to be implemented bu custom attributes (say ILocalizableAttribute) containing the following fields.
public interface ILocalizableAttribute
{
///base name of the resource file
string ResourceBaseName
{
get;
}

///type of the object of an assembly containing the resource files
///This will be used to call ResourcMemanager by hand and getting localized strings.
Type RootType
{
get;
}
}

When the addin parses the code of a project, it could look for attributes implementing this interfaces and then, look for fields marked with LocalizableAttribute.

With this, we would still have to implement calls to resource manager to retrieve localized strings but the localization process could be done through your addin : this would be much easier !

What doyou think about that ?

Germany

Hi,

I don't quite understand how this would work, but I havn't really thought enough about it. What would the definition of an attribute look like?

Actually, I have always been sceptical about localizing attributes. In most cases, attributes are used to define meta data, and there is usually no reason to localize meta data. However, I realize that there are some legitimate cases where you might want to localize attributes, so I won't rule it out.

About two years ago, I actually implemented a half feature to support attributes, for a guy in Brazil, who also sent me a test project showing how he wanted it to work. I have never developed this feature any further and never written any help on it.

I will try to describe roughly how this solution works.

The first problem is that you can't replace an attribute with a function call. The proposed solution was to code the string ID into the attribute, with a vertical line as separator, e.g. "83|Name of this custom event type".

The Add-In can do this. First you have to open the setup dialog (13th button on the toolbar), select the attributes tab and check the option "Enable Attribute Support". Don't modify the other two fields.

After that, the context menu on the check box (and only on the check box) in the source code tab has an additional option "Special encoding for attributes", which selects this encoding. You can also use Ctrl-Space.

That was easy bit, and it is all that the Add-In does. The big problem is how to handle the attributes at runtime.

The only help that I can give you is to attach you the example project that the user sent me two years ago. Note that he was also interested in localizing XML files, so I think that there is some junk in this project related to that. The stuff related to attributes is in the folder "New Files for Version B". If you try running the project, you can select portuguese and see that it actually does work.

The localized attributes are in the class person. The fundamental trick seems to be, that this class is derived from GlobalizedObject. The class GlobalizedObject overrides the function "PropertyDescriptorCollection GetProperties()" (2 overloads) and returns a collection of GlobalizedPropertyDescriptor objects, which encapsulate the original PropertyDescriptor objects.

I don't know if this kind of solution would work in your project. If so, then good luck.

Otherwise, I might look into your proposed solution, but it is not high on my list of priorities.

Phil

Hi,

Thank you for your quick answer.
I've been thinking about your solution and it is quite interesting. My only problem is that it implies a lot of changes in application code which is not useful.
You will find a proposal for a "generic" solution for localizing custom attributes using the work you already did in the addin. This visual studio solution contains 2 projects : a class library that defines some localizable attributes and a test application.

Localizable attributes should implement the ILocalizableAttribute interface : this could help you to detect these attributes and handle them automatically, without having to click on "Special encoding for attributes" in the addin. The RootType will allow us to find the assembly where localization resources should be found.
public interface ILocalizableAttribute
{
Type RootType
{
get;
}
}

Each localizable attribute has to handle calls to resource manager / ml_string to get the localized strings : this can not be done by the addin.
Example with LocalizableDescriptionAttribute :

public class LocalizableDescriptionAttribute : DescriptionAttribute, ILocalizableAttribute
{
Type _rootType;

public LocalizableDescription(string description, Type rootType)
: base(description)
{
_rootType = rootType;
}

#region ILocalizableAttribute Members

public Type RootType
{
get { return _rootType; }
}

#endregion

public override string Description
{
get
{
return mlAttributes.ml_attributeString(base.Description, this);
}
}
}

As you will see I also modified the original ml class to be able to load resources from a different assembly than the one where the attribute class is defined (we have to load resources from assemblies using the localized attribute). This "new" ml class (in MLStringAttributes.cs) could be added automatically in projects containing localized attributes. This new implementation may have to be modified again for multithread purpose (add a lock { } sections in the assembly cache management)

With this, it's now very easy to use and localize custom attributes with your addin : this is not necessary to change anything further.
- No implementation of ICustomTypedescriptor for classes that uses localized attributes. No GlobalizedPropertyDescriptor wrapping default Propertydecriptor.
- This should work with any custom attribute (not only Description/DisplayName/Category) that implement ILocalizableAttribute.

public class Person
{
private string _firstName;

public Person(string fName)
{
_firstName = fName;
}

First Name", typeof(Person))
Identity", typeof(Person))
Person's first name", typeof(Person))
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
}

What about adding such behaviour in your addin ? Be sure that I will be available for beta testing if you need ;)

Any update about this ?
Germany

Sorry, I haven't had time to really look into this.
Phil