.Net: Running code when assembly is loaded

限于喜欢 提交于 2019-12-17 04:28:31

问题


Is it possible to run some code when an assembly is loaded, without doing anything specific in the loading code? What I am looking for is like a static constructor on a type.

Eg:

Assembly A does not know about Assembly B, but B does know about A. Assembly A needs to know certain things about B if B is loaded. When Assembly B is loaded by the runtime (referenced, or explicit), I want a piece of code (static method or attribute) to be executed that calls a method in Assembly A.

The root cause of this problem is unknown types being encountered when serializing a type in A that contains types from B not known at compile time as interfaces are used.


回答1:


The CLR supports module initializers. You'd have to hack C++/CLI code or ilasm.exe to use them.




回答2:


You can use static constructors in .Net, but unfortunately they don't do what you want. Static constructors are only executed just before a type is used. See http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx for details.

You might get some mileage from subscribing to your AppDomain's AssemblyLoad event. See http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx.

In your event handler you could reflect on the newly loaded assembly, and get it to execute whatever code you like.




回答3:


(edit - applies to C#; for a C++ approach, see this answer)

Basically, no: you can't. This would be a huge attack surface, and isn't allowed. You might want to put a static ctor on some of the B types that ensure the init code is executed, but that is about it...




回答4:


There are 3 options to initialize a .NET Assembly:

  1. You write a static function Init() or Main() in your Assembly to be initialized and call this function by reflection from the C# code that loads this Assembly.
  2. Write a Managed C++ Assembly where you put your code in DllMain(). Be careful because your code will be executed in the Loader Lock where several things are forbidden (like loading other DLL's,...). But you can start a new thread that does ANY initialization stuff. (About LoaderLock: https://msdn.microsoft.com/en-us/library/ms173266.aspx) (About DllMain: C# to C++/CLI to C DLL System.IO.FileNotFoundException)
  3. You compile a pure C# Assembly and modify the compiled DLL to add a module initializer code like explained here: http://einaregilsson.com/module-initializers-in-csharp/ The disadvantage of this method is that the initialization function is not called immediately when the assembly is loaded into the process. But it is called before anything else in the assembly is first accessed.



回答5:


You should probably revisit your serialization approach to mitigate this problem. If you serialize using ISerializable and the SerializableAttribute attribute, you can make it such that the serialization graph will load assembly B when necessary without assembly A ever having to explicitly know about assembly B.




回答6:


Using a mixed assembly you can get DllMain to run on an assembly load.



来源:https://stackoverflow.com/questions/505237/net-running-code-when-assembly-is-loaded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!