我们已经构建了一个小组件,它接受一个 Id,在数据库中查找一个条目以查找程序集/命名空间/类,并动态加载我们要查找的类的实例。到目前为止它一直运行良好,但是在 VS 2010 中运行此代码时,它失败了。
Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly
Dim assemblies() As Assembly = AppDomain.CurrentDomain.GetAssemblies
For Each asmb As Assembly In assemblies
If (asmb.Location = assemblyFile)) Then Return asmb
Next
Return Nothing
End Function
第一个问题是,当迭代器命中动态程序集时,没有 asmb.Location,并抛出 NotSupportedException。有什么方法可以在不捕获异常的情况下检查 Location 字段的 Unsupported-ness 吗?
第二个问题,asmb.Location 返回的是整个路径,而不仅仅是文件名,这意味着这个函数每次都会失败。如果此函数确定某个类尚未加载,那么我们将尝试加载它并获取 AccessViolationException,因为该类已经加载并且我们无法“重新加载”它。
将函数更改为此有效:
Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly
Dim assemblies() As Assembly = AppDomain.CurrentDomain.GetAssemblies
For Each asmb As Assembly In assemblies
Try
If (asmb.Location.EndsWith(assemblyFile)) Then Return asmb
Catch ex As NotSupportedException
Continue For
End Try
Next
Return Nothing
End Function
但感觉很脏。有没有更好的方法来检查程序集是否已经加载,并将其返回给调用者?上述问题是否特定于 .NET 4.0 或 Visual Studio 2010?我没有在 IDE 之外尝试过这个,因为它需要相当重要的配置。
最佳答案
您可以通过跳过 AssemblyBuilder 的实例来检查程序集是否是动态的。您应该使用 Path.GetFileName() 来隔离名称。请注意,这不是一个好主意,因为来自不同路径的程序集可能具有相同的名称。但你似乎被这个困住了。因此:
Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly
For Each asmb As Assembly In AppDomain.CurrentDomain.GetAssemblies
If TypeOf asmb Is System.Reflection.Emit.AssemblyBuilder Then Continue For
If System.IO.Path.GetFileName(asmb.Location) = assemblyFile Then Return asmb
Next
Return Nothing
End Function
也许您也应该处理区分大小写的问题。
关于c# - 在 .NET 中动态加载程序集的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2895439/