. Net: Ejecutar código cuando se carga el ensamblado


¿Es posible ejecutar algún código cuando se carga un ensamblado, sin hacer nada específico en el código de carga? Lo que estoy buscando es como un constructor estático en un tipo.

Eg:

El Ensamblado A no sabe acerca del Ensamblado B, pero B sí sabe acerca de A. El Ensamblado A necesita saber ciertas cosas acerca de B si B es cargado. Cuando el ensamblado B es cargado por el tiempo de ejecución (referenciado o explícito), quiero que se ejecute un fragmento de código (método estático o atributo) que llame a un método en la Asamblea A.

La causa raíz de este problema son los tipos desconocidos que se encuentran al serializar un tipo en A que contiene tipos de B no conocidos en tiempo de compilación, ya que se utilizan interfaces.

Author: starblue, 2009-02-03

6 answers

El CLR soporta inicializadores de módulos . Tendrías que hackear código C++/CLI o ilasm.exe para usarlos.

 39
Author: Hans Passant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 22:56:16

(editar-se aplica a C#; para un enfoque de C++, ver esta respuesta )

Básicamente, no: no se puede. Esto sería una enorme superficie de ataque, y no está permitido. Es posible que desee poner un ctor estático en algunos de los tipos B que aseguran que el código de inicio se ejecute, pero eso es todo...

 6
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:44

Puedes usar constructores estáticos en.Net, pero desafortunadamente no hacen lo que quieres. Los constructores estáticos solo se ejecutan justo antes de que se use un tipo. Véase http://msdn.microsoft.com/en-us/library/k9x6w0hc (VS.80).aspx para más detalles.

Es posible que obtengas cierto kilometraje al suscribirte al evento AssemblyLoad de tu AppDomain. Véase http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx .

En su controlador de eventos podría reflexionar sobre el nuevo loaded assembly, y consigue que ejecute el código que quieras.

 5
Author: Antony Perkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 23:05:35

Hay 3 opciones para inicializar un ensamblado. NET:

  1. Escribe una función estática Init() o Main() en su ensamblado para inicializarla y llama a esta función por reflexión desde el código C# que carga este ensamblado.
  2. Escribe un Ensamblado C++ Administrado donde pones tu código en DllMain(). Tenga cuidado porque su código se ejecutará en el Bloqueo del cargador donde varias cosas están prohibidas(como cargar otras DLL,...). Pero puedes iniciar un nuevo hilo que haga CUALQUIER cosas de inicialización. (Acerca de LoaderLock: https://msdn.microsoft.com/en-us/library/ms173266.aspx) (Acerca de DllMain: C# a C++ / CLI a C DLL System. IO. FileNotFoundException )
  3. Compila un ensamblado C # puro y modifica el DLL compilado para agregar un código inicializador de módulo como se explica aquí: http://einaregilsson.com/module-initializers-in-csharp / La desventaja de este método es que la función de inicialización no se llama inmediatamente cuando el ensamblado es cargado en el proceso. Pero se llama antes de que se acceda por primera vez a cualquier otra cosa en el ensamblado.
 4
Author: Elmue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:01

Probablemente debería revisar su enfoque de serialización para mitigar este problema. Si se serializa usando ISerializable y el atributo SerializableAttribute, puede hacerlo de manera que el gráfico de serialización cargue el ensamblaje B cuando sea necesario sin que el ensamblaje A tenga que saber explícitamente sobre el ensamblaje B.

 3
Author: Jeff Yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 22:55:58

Usando un ensamblado mixto puede hacer que DllMain se ejecute en una carga de ensamblado.

 0
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-04 04:42:56