.Net:加载程序集时运行代码
加载程序集时是否可以运行一些代码,而不需要在加载代码中做任何特定的操作? 我正在寻找的就像一个types的静态构造函数。
例如:
大会A不知道大会B,但是B知道大会A.大会A需要知道关于B的某些事情,如果B加载。 当程序集B由运行时加载(引用或显式)时,我想要执行一个代码段(静态方法或属性),调用程序集A中的一个方法。
这个问题的根本原因是序列化A中的types时遇到的未知types,该types包含在编译时未知的B中的types,因为使用了接口。
CLR支持模块初始化器 。 你必须破解C ++ / CLI代码或ilasm.exe才能使用它们。
(编辑 – 适用于C#;对于C ++方法,请参阅此答案 )
基本上,不,你不能。 这将是一个巨大的攻击面,是不允许的。 你可能想把一个静态ctor放在一些确保init代码被执行的Btypes上,但是这是关于它的…
你可以在.Net中使用静态构造函数,但不幸的是,他们没有做你想做的事情。 静态构造函数仅在使用types之前执行。 有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx 。
订阅AppDomain的AssemblyLoad事件可能会获得一些里程。 请参阅http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx 。
在你的事件处理程序中,你可以反思新加载的程序集,并让它执行你喜欢的任何代码。
你应该重新访问你的序列化方法来缓解这个问题。 如果使用ISerializable
和SerializableAttribute
属性进行SerializableAttribute
,则可以使序列化graphics在必要时加载程序集B,而无需程序集A永远不必明确知道程序集B.
有三个选项来初始化一个.NET程序集:
- 你要在你的程序集中编写一个静态函数Init()或Main()来初始化,并通过加载这个Assembly的C#代码的reflection来调用这个函数。
- 编写一个托pipe的C ++程序集,将代码放在DllMain()中。 要小心,因为你的代码将在Loader Lock中被执行,其中有几件事是被禁止的(比如加载其他DLL,…)。 但是你可以开始一个新的线程,做任何初始化的东西。 (关于LoaderLock: https ://msdn.microsoft.com/en-us/library/ms173266.aspx)(关于DllMain: C到C ++ / CLI到C DLL System.IO.FileNotFoundException )
- 你编译一个纯粹的C#程序集并修改编译后的DLL来添加一个模块初始化程序代码,如下所示: http : //einaregilsson.com/module-initializers-in-csharp/这个方法的缺点是初始化函数没有被调用当组件被加载到进程中时立即。 但是在程序集中的其他任何东西首先被访问之前调用它。
使用混合程序集可以使DllMain在程序集上运行。