我在通过反射在其他AppDomain中加载DLL时遇到了一些麻烦。
这是我的情况。
问题在步骤3上。当我尝试在其他AppDomain中加载Test.DLL时,出现错误,因为它无法在AppDomain中找到Interfaces.Dll。消息是:
System.IO.FileNotFoundException was unhandled
FileName=BankInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
那么,如何在AppDomain中加载2个不同的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
主要应用
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
到
AddHandler LocalAppDomain.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
使用此代码在要加载的dll中调用一个方法:
Loader.Call(pathToDLL, ClasName,MethodName, parameters)
调用任何方法后,此解决方案将卸载域。因此这不是完美的,因为如果您要调用多个方法,则会在执行时间上受到惩罚。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句