页首Html代码

如何整洁地引用庞杂的dll库

 

如何编写LibraryB.dll,

LibB引用这些庞杂的库,然后AppC.exe只需要引用LibB即可。

1.设置项目引用。

LibB中设置对于LibA文件的引用,关键复制本地为false

 

2

在 LibraryB 中处理 AssemblyResolve 事件:

  • 在 LibraryB 的代码中(通常在一个静态构造函数或模块初始化器中,确保尽早注册),订阅 AppDomain.CurrentDomain.AssemblyResolve 事件。
  • 在事件处理程序中,检查请求的程序集是否属于 LibraryA。如果是,则计算出 LibA_Files 子目录的路径(通常相对于 LibraryB.dll 自身的位置),并尝试从该路径加载程序集。

 

using System;  
using System.Reflection;  
using System.IO;  

public static class AssemblyResolver  
{  
    private static readonly string _subFolderName = "LibA_Files"; // 子目录名称  
    private static string _libAPath = null;  

    // 静态构造函数,确保事件尽早注册  
    static AssemblyResolver()  
    {  
        // 计算 LibA_Files 的绝对路径  
        // 获取 LibraryB.dll 所在的目录  
        string libraryBPath = Path.GetDirectoryName(typeof(AssemblyResolver).Assembly.Location);  
        _libAPath = Path.Combine(libraryBPath, _subFolderName);  

        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;  
    }  

    // 调用此方法以确保静态构造函数被执行并注册事件  
    public static void Initialize()  
    {  
        // 这个空方法只是为了触发静态构造函数的执行  
        // 你可以在 LibraryB 的某个公共入口点或初始化逻辑中调用它一次  
    }  

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)  
    {  
        // 获取请求的程序集名称  
        string requestedAssemblyName = new AssemblyName(args.Name).Name;  

        // 根据需要,你可以更精确地判断是否是 LibraryA 的程序集  
        // 例如,检查程序集的全名、公钥标记等  
        // 这里为了简单,假设所有在 LibA_Files 目录下的 dll 都是需要的  

        string assemblyPath = Path.Combine(_libAPath, requestedAssemblyName + ".dll");  

        // 检查文件是否存在  
        if (File.Exists(assemblyPath))  
        {  
            try  
            {  
                // 从指定路径加载程序集  
                return Assembly.LoadFrom(assemblyPath);  
            }  
            catch (Exception ex)  
            {  
                // 处理加载失败的情况,例如记录日志  
                Console.WriteLine($"Error loading assembly {requestedAssemblyName} from {_libAPath}: {ex.Message}");  
                return null;  
            }  
        }  

        // 如果不是我们要处理的程序集,或者在子目录中找不到,返回 null  
        // 让 .NET 运行时继续按默认规则查找  
        return null;  
    }  
}  

// 在你的 LibraryB 的某个地方,确保调用 Initialize() 一次  
// 例如,在一个 LibraryB 提供的工厂类或初始化类中  
// public class LibraryBInitializer {  
//     public static void Init() { AssemblyResolver.Initialize(); }  
// }  
// 然后使用 LibraryB 的 AppC 需要在使用 LibraryB 功能前调用 LibraryBInitializer.Init();

 关键知识

AppDomain.CurrentDomain.AssemblyResolve什么时候,怎样被触发

代码需要类型信息: 当你的应用程序(或它引用的任何库)执行到某一行代码时,这行代码引用了尚未加载到当前应用程序域 (AppDomain) 中的某个程序集 (DLL) 中定义的类型(类、结构、接口、枚举等)或资源。

举例,在LibB中,现在想用使用var ins = new KML.CLI.TheData.Run();

相关程序就会被加载,只加载一次。

 

posted @ 2025-04-24 14:38  noigel  阅读(21)  评论(0)    收藏  举报
js脚本