Assembly.LoadFile热加载DLL时第三方依赖解析问题及替代方案咨询
DLL热加载与第三方依赖解析问题求助
问题背景
- 目标实现DLL热加载,同事使用应用时可推送更新,无需重启即可生效
- 最初使用
Assembly.LoadFrom(),但该方法倾向于加载已缓存的旧版本文件;改用Assembly.LoadFile()可加载最新版本,但需手动处理所有依赖项 - 自定义DLL的依赖问题已通过监听
AppDomain.AssemblyResolve事件解决,这部分运行正常
核心问题
- 项目依赖Autodesk Inventor 2022的DLL,这类文件不会自动生成在Visual Studio构建目录(手动添加了部分,但仍有缺失),且本地无法找到完整依赖
- 尝试加载时抛出
FileNotFoundException(非自定义异常),最先出现的是找不到Autodesk.iLogic.Core.resources.dll - 猜测可能是当前AppDomain与Inventor共享,使用
LoadFile()时需要解析Inventor自身的依赖,但无法确认原因
替代方案咨询
若上述第三方依赖解析问题无法解决,是否有其他策略可实现DLL不被锁定且无需关注版本号的热加载效果?
代码示例
Imports System.IO Imports System.Reflection Public NotInheritable Class LibInterface Private Const sBuildDir As String = "F:\Lib\Build" Private Const sReleaseRootDir As String = "F:\Lib\Releases" Private _oAssembly As System.Reflection.Assembly = Nothing Public Property oAssembly() As System.Reflection.Assembly Get Return _oAssembly End Get Protected Set(oVal As System.Reflection.Assembly) _oAssembly = oVal End Set End Property Private _oType As Type = Nothing Public Property oType() As Type Get Return _oType End Get Protected Set(oVal As Type) _oType = oVal End Set End Property Private Class Initialiser Public Sub New( ByVal oParent As LibInterface ) AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf oParent.HandleResolve End Sub End Class Private _initialiser As New Initialiser(Me) Public Function HandleResolve( ByVal sender As Object _ , ByVal args As ResolveEventArgs ) As System.Reflection.Assembly Return _GetAssembly(Split(args.Name, ",")(0) + ".dll") End Function Private Function _GetAssembly( ByVal sFileName As String ) As System.Reflection.Assembly Return System.Reflection.Assembly.LoadFile(_SearchLastBuild(sFileName)) End Function Private Function _SearchLastBuild( ByVal sFileName As String ) As String Dim sPathName = System.IO.Path.Combine(sBuildDir, sFileName) If Not File.Exists(sPathName) Then Throw New FileNotFoundException(".dll not found", sPathName) End If Dim oVersionInfo As FileVersionInfo = FileVersionInfo.GetVersionInfo(sPathName) Dim sReleaseDir As String = System.IO.Path.Combine(sReleaseRootDir, oVersionInfo.FileVersion) Dim sReleasePathName = System.IO.Path.Combine(sReleaseDir, sFileName) If File.Exists(sReleasePathName) Then Return sReleasePathName End If Directory.CreateDirectory(sReleaseDir) _CopyFilesRecursively(sBuildDir, sReleaseDir) Return sReleasePathName End Function Private Sub _CopyFilesRecursively( ByVal sSrcPath As String _ , ByVal sDestPath As String ) For Each sDirPath As String In Directory.GetDirectories(sSrcPath, "*", SearchOption.AllDirectories) Directory.CreateDirectory(sDirPath.Replace(sSrcPath, sDestPath)) Next For Each sOldPath As String In Directory.GetFiles(sSrcPath, "*.*", SearchOption.AllDirectories) File.Copy(sOldPath, sOldPath.Replace(sSrcPath, sDestPath), True) Next End Sub Public Sub New( ByVal sFileName As String _ , ByVal sType As String ) _oAssembly = _GetAssembly(sFileName) _oType = _oAssembly.GetType(sType, False) End Sub End Class
内容的提问来源于stack exchange,提问作者davidfjdkslfs
相关产品推荐
相关产品推荐

