代码之家  ›  专栏  ›  技术社区  ›  Robert Wagner

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

  •  32
  • Robert Wagner  · 技术社区  · 17 年前

    是否可以在加载程序集时运行某些代码,而不执行加载代码中的任何特定操作?我要找的是类型上的静态构造函数。

    程序集A不知道程序集B,但B知道A。如果加载了B,程序集A需要知道B的某些信息。当运行时加载程序集B(引用的或显式的)时,我希望执行一段代码(静态方法或属性),调用程序集a中的方法。

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

    6 回复  |  直到 17 年前
        1
  •  42
  •   Hans Passant    5 年前

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

    [ModuleInitializer] attribute

        2
  •  7
  •   Antony Perkov    17 年前

    http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx 详情请参阅。

    http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx .

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

        3
  •  7
  •   Community Mohan Dere    9 年前

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

    1. 在要初始化的程序集中编写一个静态函数Init()或Main(),并通过加载此程序集的C#代码的反射调用此函数。
    2. 编写一个托管C++程序集,将代码放入DLIN()中。请小心,因为您的代码将在加载程序锁中执行,其中有几项是禁止的(例如加载其他DLL…)。但是,您可以启动一个新线程来执行任何初始化操作。(关于装载机锁: https://msdn.microsoft.com/en-us/library/ms173266.aspx )(关于 C# to C++/CLI to C DLL System.IO.FileNotFoundException )
    3. 编译纯C#程序集并修改编译后的DLL以添加模块初始值设定项代码,如下所述: http://einaregilsson.com/module-initializers-in-csharp/ 此方法的缺点是,当程序集加载到进程中时,不会立即调用初始化函数。但是在第一次访问程序集中的任何其他内容之前调用它。
        4
  •  6
  •   Community Mohan Dere    9 年前

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

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

        5
  •  3
  •   Jeff Yates    17 年前

    您可能应该重新使用序列化方法来缓解此问题。如果使用 ISerializable SerializableAttribute 属性,可以使序列化图在必要时加载程序集B,而无需程序集A明确了解程序集B。

        6
  •  0
  •   Mike    16 年前