我有一个 .net 库的 dll 文件,它像一个函数库一样。其中有许多静态类型和静态方法。
我需要运行一些初始化代码,使库准备好可用。
当程序集被加载时是否有一种方法可以确保自动运行特定的方法?类似于 AppDomain.AssemblyLoad,但是从程序集本身调用。我想也许有一些 AssemblyAttribute 可以使用?
目前我将这个初始化代码放在了一个静态构造函数中,但由于这是一个具有许多入口点的库,所以无法保证一定会使用此特定类型。
谢谢!
我有一个 .net 库的 dll 文件,它像一个函数库一样。其中有许多静态类型和静态方法。
我需要运行一些初始化代码,使库准备好可用。
当程序集被加载时是否有一种方法可以确保自动运行特定的方法?类似于 AppDomain.AssemblyLoad,但是从程序集本身调用。我想也许有一些 AssemblyAttribute 可以使用?
目前我将这个初始化代码放在了一个静态构造函数中,但由于这是一个具有许多入口点的库,所以无法保证一定会使用此特定类型。
谢谢!
是的,有一种方法可以实现。可以使用由Einar Egilsson开发的优秀小工具InjectModuleInitializer。
在构建后执行此可执行文件以创建一个小的.cctor函数(模块初始化函数),它调用您的静态无参函数。如果编译器能够让我们创建.cctor(),那会很好,幸运的是我们很少需要这个功能。
然而,这并不是完整的DllMain替代品。CLR仅在调用程序集中的任何方法之前调用此.cctor函数,而不是在程序集加载时调用。因此,如果您需要在程序集加载时执行某些操作,则需要直接调用某个方法或者使用我在https://dev59.com/fWsy5IYBdhLWcg3w9Srk#9745422中详细介绍的技巧。
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class InitializeOnLoadAttribute : Attribute
{
Type type;
public InitializeOnLoadAttribute(Type type) { this.type = type; }
public Type Type { get { return type; } }
}
// somewhere very early in main exe initialization
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(AssemblyInitializer);
static void AssemblyInitializer(object sender, AssemblyLoadEventArgs args)
{
// force static constructors in types specified by InitializeOnLoad
foreach (InitializeOnLoadAttribute attr in args.LoadedAssembly.GetCustomAttributes(typeof(InitializeOnLoadAttribute), false))
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(attr.Type.TypeHandle);
}
另外,如果您担心在挂钩AssemblyLoad事件之前已经加载程序集,可以通过运行AppDomain.GetAssemblies()并为它们调用“初始化器”来解决该问题。
只需要在 <Module>
类中添加一个静态构造函数即可实现。但是我不知道如何在没有 IL 修改的情况下完成此操作。
Vector3
的第三方库。还有一个操作注册表的库,您可以为任何类型注册操作(例如,添加或转换)。现在有一个实现和使用向量操作的几何库。几何库想要在操作注册表中注册向量操作。此初始化应在程序集加载时执行。这是可能的-只需将静态构造函数添加到<Module>
类即可。 - Ark-kun