当前位置:  开发笔记 > 编程语言 > 正文

在装配加载时初始化库

如何解决《在装配加载时初始化库》经验,为你挑选了3个好方法。

我有一个.net库dll,就像一个函数库.有许多静态类型和静态方法.

我需要运行一些初始化代码来设置库以供使用.

当程序集加载时,是否有办法确保运行特定方法?像AppDomain.AssemblyLoad之类的东西,但是从程序集本身自动调用.我在想,也许有可能会使用像AssemblyAttribute这样的东西?

目前我在静态构造函数中有这个初始化代码,但由于这是一个包含许多入口点的库,因此无法保证将使用此特定类型.

谢谢!



1> mheyman..:

是的 - 有点 - 有点.

使用Einar Egilsson,InjectModuleInitializer的优秀小工具.

将此可执行文件作为后期构建步骤运行,以创建一个小的.cctor函数(模块初始化函数),该函数调用不带参数的静态void函数.如果编译器给我们创建.cctor()的能力会很好,幸运的是我们很少需要这种能力.

但是,这不是一个完整的DllMain替代品.CLR仅在程序集中调用的任何方法之前调用此.cctor函数,而不是在程序集加载时调用.cctor函数.所以,如果你需要在组装加载时发生一些事情,你需要让加载代码直接调用一个方法或者使用hack我详细的/sf/ask/17360801/



2> 小智..:

只有当您可以控制主执行程序集时,才能使用以下解决方案,即它不适合用于分发的独立库

我遇到了类似的问题,并通过使用Type参数创建一个以程序集为目标的属性"InitializeOnLoad"来解决它.然后,在主可执行文件中,我添加了一个简单的AppDomain.AssemblyLoaded处理程序,该处理程序扫描新加载的程序集以获取上述属性,并对它们调用System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor().

[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()并为它们调用'初始化程序'.



3> Jon Skeet..:

为什么在使用任何数据之前需要加载所有数据,而不是在使用需要它的第一种类型时?

我不相信有任何方法可以在程序集内部强制从程序集加载运行方法.您可以在每种类型中放置一个静态构造函数,但坦率地说,我认为只有一种类型表示数据并提供对它的访问才更有意义 - 并且仅在该类型上放置静态构造函数.(如果您有可以单独使用的单独数据位,可能会为它们创建单独的类型.)


实际上,人们可能希望代码在程序集加载时运行 - 例如,如果涉及到昂贵的初始化,最好在一个地方解决.当然,人们可以通过手动查找程序集中的一些初始化例程并执行它来解决这个问题,但框架是否提供内置方法来执行此操作的问题确实存在.
@JonSkeet"为什么在使用任何数据之前需要加载所有数据?" 假设有一个类型为'Vector3`的第三方库.还有一个带有操作注册表的库,您可以在其中注册任何类型的操作(例如,添加或转换).现在有一个实现和使用向量操作的几何库.几何库想要在操作注册表中注册向量操作.应在装配负载上执行此初始化.并且它是可能的 - 只需在``类中添加一个静态构造函数.
推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有