将DLL加载到其他AppDomain及其依赖项中

伦普斯汀斯克

我在通过反射在其他AppDomain中加载DLL时遇到了一些麻烦。

这是我的情况。

  1. 我有一个叫Interfaces.DLL的DLL,它只包含一个接口Definition。
  2. Test.DLL包含Interfaces.DLL,并定义了一个名为Connector的类,该类实现了在以前的dll上定义的接口。
  3. 我有一个仅包含Interfaces.dll的应用程序,需要使用反射来加载Test.dll
  4. 我调用类连接器的公共方法,该方法向我返回通过反射加载的dll文件的DLL版本。在那之后,我调用一个Web服务来检查我是否具有该文件的更高版本。如果没有,我必须卸载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的建议,但他的评论帮助我找到了解决方案。所以,谢谢您抽出宝贵的时间来帮助我:)

对于我这种情况的任何人,这都是可行的解决方案:

  1. 您要反序列化的类必须继承自MarshalByRefObject
  2. 类内部方法返回的对象必须可序列化
  3. 创建此类:

    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
    
  4. 使用此代码在要加载的dll中调用一个方法:

    Loader.Call(pathToDLL, ClasName,MethodName, parameters)
    

调用任何方法后,此解决方案将卸载域。因此这不是完美的,因为如果您要调用多个方法,则会在执行时间上受到惩罚。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C#将DLL字节数组加载到其他AppDomain中会引发System.IO.FileNotFoundException

Xamarin.Form 将依赖项 dll 加载到 apk 和 ipa

将工件及其依赖项上载到远程存储库

使用临时表删除其他表中的重复行及其依赖项

CMake并查找其他项目及其依赖项

将清单程序集动态加载到 appdomain 中

将多个程序集版本加载到多个AppDomain中

git-remote-https无法将msys-unistring-2.dll加载到其他地址

如何诊断dnx中缺少依赖项(或其他加载程序故障)?

SQL Loader-使用TERMINATED将数据加载到其他表中

将数据加载到片段中,然后在其他类中使用该数据

将腌制的对象加载到其他文件中-属性错误

在其他平板电脑上单击行时将数据加载到tableview中

如何将模型加载到其他控制器中

将异步函数直接导出为模块不会加载到其他模块中

如何加载Javascript及其依赖项?

JavaFx将其他FXML加载到FXML“模板”中

Javascript无法将其他页面加载到DIV中

如何从默认的中央Maven和其他公共仓库下载Maven jar及其依赖项?

具有其他dll作为依赖项的C ++ dll(SDL2)

如何强制npm将依赖项的依赖项解析为其他程序包?

将动态optgroup项加载到html select中

如何覆盖composer.json中的其他依赖项

Eclipse:在 WAR 中包含其他项目的依赖项

常春藤解决其他配置中的依赖项

为什么PaaS提供程序建议在部署过程中安装依赖项?(对于PHP或NodeJS以及其他可能的对象)

将程序集加载到applicationBase C#的AppDomain异地

pandas.read_csv与其他用于将CSV加载到Postgres数据库中的csv库

Odoo 11.0仅在渲染模板时才将CSS /脚本或其他内容加载到<head>中