Pergunta

initializers módulo são um recurso do CLR que não são directamente disponível em C # ou VB.NET. Eles são métodos globais estático chamado .cctor que são garantidos para executar antes de qualquer outro código (tipo initializers, construtores estáticos) em uma montagem são executados. Recentemente queria usar isso em um projeto e hackeada juntos meu próprio solução (programa de console / tarefa msbuild) usando Mono.Cecil, mas eu queria saber:

  1. Existe alguma maneira de enganar o compilador C # para emitir intializers módulo? Quaisquer atributos (por exemplo CompilerGenerated, SpecialName) ou outro artifício que poderiam ser utilizados?

  2. Faça o C # / VB.NET já emitem estes próprios initializers para algum propósito? Pelo que tenho visto que eles são usados ??por C ++ gerenciado para alguns fins de interoperabilidade, mas eu não consegui encontrar qualquer referência a eles sendo usados ??para outros fins. Alguma idéia?

Foi útil?

Solução

Não, não há nenhuma maneira de emiti-las em C #, porque C # coloca tudo em uma classe / struct e módulo initializers precisa ser global.

Você terá que usar uma ferramenta diferente para escrevê-los, de preferência IL-Assembler.

Quanto à segunda pergunta, eu tenho que admitir que eu não sei, mas eu nunca vi nenhum gerado por C #, e eu uso ILDasm muitas vezes, então eu suponho que ele não emiti-las.

Outras dicas

Confira o módulo initializer addon do incrível opensource projeto IL-Weaver " fody ", escrito por Simon Cropp: https://github.com/fody/moduleinit

Ele permite que você especifique um método que vai ser traduzido em uma montagem initializer por fody:

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

recebe este:

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

Talvez System.Reflection.Emit namespace pode ajudá-lo. MethodAttributes enumeração contém elementos semelhantes (SpecialName, RTSpecialName).

Einar, Sua pergunta não deixou claro para mim que você já escreveu uma ferramenta que permite injetar um módulo initializer em uma Assembléia já compilado.

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

Eu tentei o seu pedido e ele funciona perfeitamente. Como você escreve ele deve funcionar com todas as estruturas atuais 2-4,5.

Não é apenas um problema que faz com que a sua solução inútil para mim: Seu initializer é chamado quando o aplicativo primeiro ACESSOS nada na montagem.

O que eu preciso é que o módulo inicializador deve ser chamado imediatamente quando o conjunto é carregado no processo. Mas não é. Então, se a aplicação não acessa a montagem nunca será inicializado.

Depois de investigar um dia inteiro parece-me que a única maneira de conseguir isso é escrever um assembly gerenciado C ++ e executar o código no DllMain ().

Se você tem construtores estáticos ou classes únicas que você pode acessar verdade uma variável estática C # compilador irá emitir .cctor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top