'Hot-loading' .dll's

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello
I have this class which will hopefully let me essentially hot-load my .dll's, so that I can push changes to them while my coworkers are using them, without needing them to totally restart their applications to begin seeing the effects.
I had been using `.LoadFrom()`, but found it prefers using already-loaded versions of the files, whereas `.LoadFile()` is guaranteed to take the latest. The catch being that any dependencies the loaded file needs have to be resolved as well. But I've managed to do this by listening to the `AppDomain.AssemblyResolve` event, and it seems to work for any of the custom .dll's, which are all located in the same folder.
But we also have third-party dependencies (Autodesk Inventor 2022 .dll's) which my Visual Studio projects/solution don't generate automatically in my build folder (despite a couple I *have* had to include), and which I can't find anywhere on my machine. I've tried using `.Load()` for these, but it doesn't find anything (again, I guess, because they don't seem to be actually on my machine; the first one I consistently encounter is "Autodesk.iLogic.Core.resources.dll").
A 'FileNotFoundException' (not the one in the class) is thrown when the script instantiating the class runs within Inventor, so maybe my `AppDomain`(?) is the same as Inventor's, and by using `.LoadFile()` I'm obligated to resolve Inventor's dependencies too, but I really have no idea.
Has anyone encountered anything like this before?
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(String.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
Any advice or guidance is much appreciated
Thanks!