2011-07-29 13 views
9

Imagine que está trabajando en un proyecto .Net 4.0 que se compone de cientos de ensamblajes, cada uno con su propio archivo de recursos (.resx) para la localización. Las cadenas localizadas se accede desde C# a través de clases auto-generado con ResXFileCodeGenerator (que crea un archivo "ResourceFile.Designer.cs"): string test = ResourceFile.TestString;Cómo hacer herencia de los archivos de recursos (resx)

Cada conjunto ha localizado cadenas que son particulares a ella, pero no son cadenas que son común a todas las asambleas. Te dices a ti mismo que sería bueno tener esas "cadenas comunes" en un archivo de recursos "padre", en el cual el código retrocedería si la clave de recursos no está disponible en el archivo de recursos "local". Entonces dices "hey, la herencia podría funcionar aquí". Y de hecho, hacer algo como esto en el archivo de diseñador generado automáticamente funciona: internal class ResourceFile : ParentResourceFile Es decir, las cadenas no definidas en ResourceFile, pero definidas en ParentResourceFile, todavía se puede acceder con ResourceFile.StringInParentFile.

Pero algo en problemas de cabecera del archivo del diseñador que: "cambios en este archivo pueden provocar un funcionamiento incorrecto y se perderán si el código se regenera." Además, usted sabe jugar en los archivos de diseño generados automáticamente es mal visto. Así se llega aquí, y le preguntas:

  • ¿Cuándo generan ResXFileCodeGenerator/regenerar la clase diseñador ?
  • ¿Hay alguna manera de desactivar esa autogeneración?
  • ¿Tendremos para renunciar a las ventajas de ResXFileCodeGenerator e implementar nuestro propio manejo de ResourceManager ?

Y dices "gracias".

Respuesta

5

Después de investigar el problema por un tiempo, me he conformado con una solución: haga la herencia no en los archivos de recursos, sino en las clases que necesitan acceder a los recursos "principales".

Sólo es necesario tener una clase base cuyo proyecto incluye un archivo de recursos "maestro", y establezca la propiedad CustomTool de ese archivo de recursos a PublicResXFileCodeGenerator (la parte "pública" es importante, ya que creará una clase public, como opuesto a un internal uno). Una restricción es que PublicResXFileCodeGenerator solo está disponible a partir de VS2008 (este CodeProject article podría ser útil).

Luego, en las clases que necesitan acceder a los recursos "maestros", sólo tiene que heredan de la clase base y acceder a los recursos de la siguiente manera:

public class ChildClass : BaseClass 
{ 
    string test = BaseClass.BaseResourceFile.TestString; // a common resource 
    string localResource = ResourceFile.OtherString;  // a local resource 
} 

Un inconveniente de esta solución es que hay que hacer referencia explícita BaseResourceFile para acceder a los recursos definidos allí; no hay retroceso en la clase principal como lo habría si la herencia se hiciera directamente entre las clases de Recursos.

Y para la posteridad, voy a responder a mis propias preguntas:

  • ¿Cuándo generan ResXFileCodeGenerator/regenerar la clase diseñador ?

    Siempre que se agregue/elimine/modifique un recurso.

  • ¿Hay alguna manera de desactivar esa autogeneración?

    No. Y de todos modos, una herramienta de "generador de código" sin autogeneración sería bastante inútil, ¿no crees?

  • ¿Tendremos que renunciar a las ventajas de ResXFileCodeGenerator e implementar nuestro propio manejo de ResourceManager ?

    No, ver respuesta anterior.

También se consideró la implementación de una solución de uso de archivos "vinculados" (desde el diálogo "Agregar elemento existente", usando la opción "Agregar enlace"), donde archivo de recursos de uno de los padres estaría vinculada a todas nuestras asambleas, pero dado que nuestras asambleas ya heredan de una clase base, parecía mucho mejor seguir el camino de la herencia.

Realmente no me siento cómodo aceptando mi propia respuesta, por lo que si alguien encuentra una mejor solución o mejoras en mi solución, con mucho gusto lo aceptaré. Es decir, si a alguien le importa en absoluto.

+0

esto no funcionó para mí ... ¿Cómo lo hizo para que pudiera llamar a "BaseClass.BaseResourceFile.TestString"? – Denis

Cuestiones relacionadas