Pregunta

inicializadores módulo son una característica de la CLR que no están directamente disponibles en C # o VB.NET. Son métodos estáticos globales nombrados .cctor que están garantizados para funcionar antes de que cualquier otro tipo de código (tipo inicializadores, constructores estáticos) en una asamblea se ejecutan. Hace poco quería utilizar esto en un proyecto y hackeado mi propia solución (programa de consola / tarea msbuild) usando Mono.Cecil, pero me preguntaba:

  1. ¿Hay alguna manera de engañar al compilador de C # en emitiendo intializers módulo? Cualquier atributo (por ejemplo CompilerGenerated, SpecialName) u otro engaño que podrían ser utilizados?

  2. Hacer el C # / VB.NET nunca emiten estos mismos inicializadores para algún propósito? Por lo que he visto que son utilizados por C ++ administrado para algunos fines de interoperabilidad, pero no pude encontrar ninguna referencia a que sean utilizados para otros fines. ¿Alguna idea?

¿Fue útil?

Solución

No, no hay manera de emitir en C #, C #, porque pone todo en una clase / struct y módulos inicializadores tienen que ser global.

Usted tendrá que utilizar una herramienta diferente para escribirlas, preferiblemente IL-ensamblador.

En cuanto a la segunda pregunta, tengo que admitir que no sé, pero nunca he visto ninguna generado por C #, y utilizo ILDASM muy a menudo, así que supongo que no emite ellos.

Otros consejos

Salida del complemento módulo de inicialización del impresionante proyecto de código abierto IL-Weaver " fody ", escrito por Simon Cropp: https://github.com/fody/moduleinit

Se le permite especificar un método que se traduce en un inicializador de montaje por fody:

public static class ModuleInitializer
{
    public static void Initialize()
    {
        //Init code
    }
}

obtiene lo siguiente:

static <Module>()
{
    ModuleInitializer.Initialize();
}

Tal vez System.Reflection.Emit espacio de nombres puede ayudar. enumeración MethodAttributes contiene elementos similares (SpecialName, RTSpecialName).

Einar, Su pregunta no hizo claro para mí que ya ha escrito una herramienta que permite inyectar un inicializador módulo en una Asamblea ya compilado.

http://einaregilsson.com/module-initializers-in-csharp

He intentado su aplicación y funciona perfectamente. A medida que escribe que debería funcionar con todos los marcos de rendimiento, de 2 a 4,5.

Sólo hay un problema que hace que su solución inútil para mí: Su inicializador se llama cuando la aplicación accede por primera vez a nada en el montaje.

Lo que necesito es que el módulo de inicialización se debe llamar inmediatamente cuando la Asamblea se carga en el proceso. Pero no lo es. Así que si la aplicación no accede a la asamblea que nunca se inicializará.

Después de investigar un día entero me parece que la única manera de conseguir esto es escribir una Asamblea de C ++ y ejecutar el código en DllMain ().

Si usted tiene constructores estáticos o clases simples que se pueda acceder verdad una variable estática compilador de C # emitirá .cctor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top