.net 将DLL加载到不同的AppDomain及其依赖项中
我在不同的AppDomain中通过反射加载DLL时遇到了一些问题 这是我的设想.net 将DLL加载到不同的AppDomain及其依赖项中,.net,vb.net,reflection,appdomain,.net,Vb.net,Reflection,Appdomain,我在不同的AppDomain中通过反射加载DLL时遇到了一些问题 这是我的设想 我有一个名为Interfaces.DLL的DLL,它只包含一个接口定义 Test.DLL包含Interfaces.DLL并定义一个名为Connector的类,该类实现在以前的DLL上定义的接口 我有一个只包含Interfaces.dll的应用程序,需要使用反射加载Test.dll 我调用类连接器的一个公共方法,该方法返回反射加载的DLL文件的DLL版本。之后,我调用一个web服务来检查是否有更高版本的文件。如果没有,
System.IO.FileNotFoundException was unhandled
FileName=BankInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
那么,如何在AppDomain中加载2个不同的Dll
这是我的代码:
接口.DLL
Public Interface BankInterface
Function getDLLVersion() As Double
'Other methods here
End Interface
Public Class Connector
Implements BankInterfaces.BankInterface
Public Function getDLLVersion() As Double Implements BankInterfaces.BankInterface.getDLLVersion
Return 2.5
End Function
Test.DLL
Public Interface BankInterface
Function getDLLVersion() As Double
'Other methods here
End Interface
Public Class Connector
Implements BankInterfaces.BankInterface
Public Function getDLLVersion() As Double Implements BankInterfaces.BankInterface.getDLLVersion
Return 2.5
End Function
main应用程序
Public Sub Main()
Dim domainSetup As New AppDomainSetup
domainSetup.ApplicationName = appDomainName
domainSetup.ApplicationBase = "C:\Users\jferrer.GLOBAL\AppData\Roaming\Enterprise\AppName\DllFiles\"
Dim LocalAppDomain As AppDomain = AppDomain.CreateDomain("BankDLL" & Guid.NewGuid.ToString.GetHashCode.ToString("x"), Nothing, domainSetup)
AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf CurrentDomain_AssemblyResolve
LocalAppDomain.CreateInstanceFrom("C:\Users\jferrer.GLOBAL\AppData\Roaming\Enterprise\AppName\DllFiles\TestDLL.dll", "TestDLL.Connector") 'This line throw the error
Dim conector As Type = LocalAppDomain.GetType()
'Irrelevant code here
end sub
Private Function CurrentDomain_AssemblyResolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly
Try
Dim myassembly As Assembly = Assembly.Load(args.Name)
If Not IsNothing(myassembly) Then
Return myassembly
End If
Catch ex As Exception
End Try
Dim parts As String() = args.Name.Split(",")
Dim myfile As String = "C:\Users\jferrer.GLOBAL\AppData\Roaming\Enterprise\AppName\DllFiles\" & parts(0).Trim() & ".dll"
Return Assembly.LoadFrom(myfile)
end function
更新:
如果我改变
AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf CurrentDomain_AssemblyResolve
到
我从Visual Studio收到一条警告:
Warning 1 Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. C:\Proyectos\BANK\BankTest\Form1.vb 49 20 BankTest
虽然我没有直接应用@James Barras的建议,但他的评论帮助我找到了这个解决方案。所以,谢谢你花时间帮助我:) 这对我这种情况下的任何人来说都是可行的解决方案:
Imports System.Reflection
Public Class Loader
Inherits MarshalByRefObject
Private Function CallInternal(dll As String, typename As String, method As String, parameters As Object()) As Object
Dim a As Assembly = Assembly.LoadFile(dll)
Dim o As Object = a.CreateInstance(typename)
Dim t As Type = o.[GetType]()
Dim m As MethodInfo = t.GetMethod(method)
Return m.Invoke(o, parameters)
End Function
Public Shared Function [Call](dll As String, typename As String, method As String, ParamArray parameters As Object()) As Object
Dim dom As AppDomain = AppDomain.CreateDomain("MyNewDomain")
Dim ld As Loader = DirectCast(dom.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, GetType(Loader).FullName), Loader)
Dim result As Object = ld.CallInternal(dll, typename, method, parameters)
AppDomain.Unload(dom)
Return result
End Function
End Class
Loader.Call(pathToDLL, ClasName,MethodName, parameters)
此解决方案在您调用任何方法后卸载域。因此它并不完美,因为如果您想调用多个方法,您将在执行时间上受到惩罚。AssemblyResolve不应该在LocalAppDomain上吗?这不是必需的。AssemblyResolved是共享成员:我知道什么是共享成员。不是。您想要
LocalAppDomain.AssemblyResolve
而不是LocalAppDomain.CurrentDomain.AssemblyResolve
程序集解析事件在BankTest中,因此需要加载该事件以连接程序集解析事件,但您移动了应用程序库。所以它找不到它