Inicializar biblioteca no carregamento de assembly

Eu tenho uma dll de biblioteca .net que age como uma biblioteca funcional. Há um monte de tipos estáticos, juntamente com methods estáticos.

Há algum código de boot que preciso executar para configurar a biblioteca pronta para uso.

Quando o assembly é carregado, existe uma maneira de garantir que um determinado método seja executado? Algo como AppDomain.AssemblyLoad, mas chamado automaticamente a partir do próprio assembly. Eu estava pensando que talvez haja algo como um AssemblyAttribute que poderia ser usado?

No momento eu tenho este código de boot em um construtor estático, mas como esta é uma biblioteca com muitos pontos de input, não há garantia de que esse tipo específico será usado.

Obrigado!

Por que você precisa que todos os dados sejam carregados antes de qualquer um deles ser usado, e não apenas quando o primeiro tipo que precisa dele é usado?

Eu não acredito que haja alguma maneira de forçar um método a ser executado na carga de assembly, de dentro da assembly. Você poderia colocar um construtor estático em cada tipo, mas, francamente, acho que faz mais sentido ter um único tipo representando esses dados e fornecendo access a ele – e colocar um construtor estático apenas nesse tipo. (Se você tiver bits separados de dados que podem ser usados ​​independentemente, talvez crie tipos separados para eles.)

Sim, existe – mais ou menos.

Use a excelente utilidade de Einar Egilsson, InjectModuleInitializer .

Execute este executável como uma etapa de pós-compilation para criar uma pequena function .cctor (a function inicializadora do módulo) que chama uma function void estática que não recebe parâmetros. Seria legal se o compilador nos desse a habilidade de criar .cctor (), felizmente raramente precisaríamos dessa capacidade.

Esta não é uma substituição completa de DllMain, no entanto. O CLR só chama essa function .cctor antes de qualquer método chamado em sua assembly, não na carga de assembly. Então, se você precisar de algo para acontecer na carga de assembly, você precisa ter o código de carregamento chamar um método diretamente ou usar o hack que eu detalhei https://stackoverflow.com/a/9745422/240845

A seguinte solução só é possível quando você tem controle sobre a assembly executora principal, ou seja, ela não é adequada para bibliotecas independentes destinadas a distribuição

Eu tive um problema semelhante e resolvi isso criando um atributo de direcionamento de assembly ‘InitializeOnLoad’ com um parâmetro Type. Em seguida, no executável principal, adicionei um manipulador AppDomain.AssemblyLoaded trivial, que varre o assembly recém-carregado para o atributo mencionado anteriormente e chama System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor () neles.

 [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public class InitializeOnLoadAttribute : Attribute { Type type; public InitializeOnLoadAttribute(Type type) { this.type = type; } public Type Type { get { return type; } } } // somewhere very early in main exe initialization AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyInitializer); static void AssemblyInitializer(object sender, AssemblyLoadEventArgs args) { // force static constructors in types specified by InitializeOnLoad foreach (InitializeOnLoadAttribute attr in args.LoadedAssembly.GetCustomAttributes(typeof(InitializeOnLoadAttribute), false)) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(attr.Type.TypeHandle); } 

Além disso, se você tem medo de que os assemblies tenham sido perdidos antes de ligar o evento AssemblyLoad, você pode simplesmente executar AppDomain.GetAssemblies () e chamar o ‘inicializador’ para eles.

É possível – basta adicionar um construtor estático à class . Eu não sei como conseguir isso sem a modificação do IL.