Замена статических свойств ресурса с помощью 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). Вы можете взять этот код и изменить его для создания пользовательских классов, которые делают то, что вам нужно.

Тем не менее, я думаю, что динамика не то, что вы хотите здесь. Скорее можно создавать геттеры таким образом, чтобы они реализовывали логику, которую вы хотите выполнить. Например, я хотел бы убедиться, что если ресурс не найден, что-то всегда возвращается - никогда не пустое или пустое значение. Поэтому, если ресурс отсутствует, я возвращаю идентификатор ресурса, который лучше, чем ничего.

Другие вопросы по тегам