Замена статических свойств ресурса с помощью DynamicObject
В нашем приложении есть тысячи применений статических свойств в Resources.designer.cs
файлы. Например:
Resources.string_to_identify_the_resource
У нас также есть свой собственный класс, который ищет ресурсы, но также позволяет переопределять ресурсы из других сборок. Это полезно, если у нас есть клиент, который хочет переименовать плагин или продукты, так как нам просто нужно добавить dll и все готово. Этот класс используется как:
Resources.GetString("string_to_identify_the.resource");
Мы хотим, чтобы все наши ресурсы просматривались через наш собственный класс Resources, чтобы их можно было переопределить, и мне было поручено это сделать. Мне не нравится проходить и перефакторинг всего кода.
Моя первоначальная идея состояла в том, чтобы использовать пользовательский DynamicObject:
public class Resources
{
public static dynamic Dynamic = new StaticResourcesDynamicObject();
class StaticResourcesDynamicObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = GetString(binder.Name);
return true;
}
}
// Existing code to lookup resources
public static string GetString(string name)
{
...
}
}
Так
Resources.string_to_identify_the_resource
будет просто переименован в:
Resources.Dynamic.string_to_identify_the_resource
Основная проблема заключается в том, что многие имена ресурсов содержат точки (.
) поэтому они не соответствуют статическим свойствам. Например Cmd.Too_Much
имеет статическое свойство Cmd_Too_Much
,
Я мог бы просто попытаться извлечь все различные возможности, или у кого-нибудь еще есть решение проблемы?
1 ответ
Для этого вам нужно создать собственный генератор кода, потому что Visual Studio генерирует ресурсы для вас. Сгенерированные классы являются статическими, не расширяемыми и очень тесно связаны с.NET ResourceManager, который работает с Resx.
Вы можете изменить это, создав собственный генератор ресурсов со строгой типизацией и заменив его в Visual Studio. Visual Studio использует ResXFileCodeGenerator
а также PublicResXFileCodeGenerator
или вы можете создать автономный инструмент, который запускает все файлы Resx в проекте и генерирует собственные строго типизированные классы ресурсов.
Если вы хотите получить представление о том, как вы можете это сделать, вы можете взглянуть на https://github.com/RickStrahl/Westwind.Globalization, которая включает в себя StronglyTypedResources
класс, который делает это для создания строго типизированных классов для ресурсов базы данных (или Resx). Вы можете взять этот код и изменить его для создания пользовательских классов, которые делают то, что вам нужно.
Тем не менее, я думаю, что динамика не то, что вы хотите здесь. Скорее можно создавать геттеры таким образом, чтобы они реализовывали логику, которую вы хотите выполнить. Например, я хотел бы убедиться, что если ресурс не найден, что-то всегда возвращается - никогда не пустое или пустое значение. Поэтому, если ресурс отсутствует, я возвращаю идентификатор ресурса, который лучше, чем ничего.