.Net:加载程序集时运行代码

时间:2009-02-02 22:30:10

标签: .net wcf assemblies

在加载程序集时是否可以运行某些代码,而无需在加载代码中执行任何特定操作?我正在寻找的就像一个类型的静态构造函数。

例如:

程序集A不知道程序集B,但B确实知道A.如果加载B,程序集A需要知道关于B的某些事情。当程序集B由运行时加载(引用或显式)时,我想要执行一段代码(静态方法或属性)来调用程序集A中的方法。

此问题的根本原因是序列化A中的类型时遇到的未知类型,该类型包含B中的类型,这些类型在编译时未知,因为使用了接口。

6 个答案:

答案 0 :(得分:39)

CLR支持module initializers。您必须破解C ++ / CLI代码或ilasm.exe才能使用它们。

答案 1 :(得分:6)

(编辑 - 适用于C#;对于C ++方法,请参阅this answer

基本上,不,你不能。这将是一个巨大的攻击面,是不允许的。您可能希望在确保执行init代码的某些B类型上放置静态ctor,但这是关于它...

答案 2 :(得分:5)

您可以在.Net中使用静态构造函数,但遗憾的是它们并不能满足您的需求。静态构造函数仅在使用类型之前执行。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx

订阅AppDomain的AssemblyLoad事件可能会有一些里程。见http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx

在您的事件处理程序中,您可以反思新加载的程序集,并让它执行您喜欢的任何代码。

答案 3 :(得分:4)

初始化.NET程序集有3个选项:

  1. 在程序集中编写静态函数Init()或Main()以进行初始化,并通过加载此程序集的C#代码的反射来调用此函数。
  2. 编写一个托管C ++程序集,将代码放在DllMain()中。要小心,因为你的代码将在Loader Lock中执行,其中禁止了几件事(比如加载其他DLL' ...)。但是你可以启动一个新的线程来执行任何初始化的东西。 (关于LoaderLock: https://msdn.microsoft.com/en-us/library/ms173266.aspx)(关于 DllMain的: C# to C++/CLI to C DLL System.IO.FileNotFoundException
  3. 编译纯C#程序集并修改已编译的DLL以添加模块初始化程序代码,如下所述: http://einaregilsson.com/module-initializers-in-csharp/ 此方法的缺点是在将程序集加载到进程中时不会立即调用初始化函数。但是在首次访问程序集中的任何其他内容之前调用它。

答案 4 :(得分:3)

您可能应该重新访问序列化方法来缓解此问题。如果使用ISerializableSerializableAttribute属性进行序列化,则可以使序列化图在必要时加载程序集B而不需要程序集A必须明确了解程序集B.

答案 5 :(得分:0)

使用混合程序集,您可以让DllMain在程序集加载时运行。