如何整洁地引用庞杂的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();
相关程序就会被加载,只加载一次。

浙公网安备 33010602011771号