在我的应用程序中,我想加载驻留在网络共享上的程序集(应用程序本身也在该共享上),而不必将它们添加到项目的输出路径中。我想要的是一个输出目录,其中几乎只包含应用程序。
仅仅将目标目录添加到我的项目的引用路径是行不通的。
我尝试在 App.Config 中设置探测目录,但这不起作用(甚至在我的本地磁盘而不是网络共享上对其进行了测试)
提前感谢您的任何提示!
编辑:似乎这是通过反射导致的。难道没有更优雅的方式使用像 NInject 这样的依赖注入容器吗?
在我的应用程序中,我想加载驻留在网络共享上的程序集(应用程序本身也在该共享上),而不必将它们添加到项目的输出路径中。我想要的是一个输出目录,其中几乎只包含应用程序。
仅仅将目标目录添加到我的项目的引用路径是行不通的。
我尝试在 App.Config 中设置探测目录,但这不起作用(甚至在我的本地磁盘而不是网络共享上对其进行了测试)
提前感谢您的任何提示!
编辑:似乎这是通过反射导致的。难道没有更优雅的方式使用像 NInject 这样的依赖注入容器吗?
我会看看Assembly.LoadFrom。您可以编写如下代码:
Assembly myAssembly = Assembly.LoadFrom(assemblyPath);
请注意,您还需要加载任何依赖程序集。一旦你有了这个,你可以使用以下方法创建对象:
object myObject = myAssembly.CreateInstance(typeName);
并将其转换为 typeName 指定的类型
不幸的是,您不能在探测路径中添加任意目录:只能在应用程序中添加一个子目录。
但是,可以<codeBase>
使用<assemblyBinding>
. MSDN 页面<assemblyBinding>
上有一个示例。缺点是您需要明确列出应用程序引用的所有程序集的路径。
另一种选择是在运行时Assembly.LoadFrom
通过反射加载程序集并调用方法。如果你走这条路,你必须阅读Suzanne Cook 的博客。如果您没有阅读其他内容,请阅读选择绑定上下文。
如果我理解正确,您想从程序集中加载类而不必引用程序集的项目?
然后你可以使用这个类来获取所有实现/继承某个类型的类型:
Imports System.IO
Imports System.Threading
Imports Exceptions
Imports System.Reflection
Imports ModuleInterfaces
Public Class StartupLoader
Private ReadOnly syncroot As New Object
Private _handler As ExceptionHandler ' custom class to handle exceptions'
Private _typeToLoad As Type
Public Sub New(ByVal typeToLoad As Type, _
ByVal handler As ExceptionHandler)
_handler = handler
_typeToLoad = typeToLoad
End Sub
Public Function LoadDLLs() As List(Of Type)
Dim threads As New List(Of Thread)
Dim types As New List(Of Type)
Dim exceptions As New List(Of Exception)
Dim folders As New Stack(Of String)
Dim t As Thread
folders.Push(Directory.GetCurrentDirectory) ' change to your dir here, could use a member var'
While Not folders.Count = 0
For Each f In Directory.GetFiles(folders.Peek)
Dim tmp As String = f
If tmp.ToLower.EndsWith(".dll") OrElse _
tmp.ToLower.EndsWith(".exe") Then
t = New Thread(AddressOf LoadDLLsThread)
t.Start(New Object() {tmp, types, exceptions})
threads.Add(t)
End If
Next
For Each d In Directory.GetDirectories(folders.Peek)
folders.Push(d)
Next
folders.Pop()
End While
For Each t In threads
t.Join()
Next
If exceptions.Count > 0 Then
Throw New ThreadedException(exceptions) ' Custom exception containing a List(Of Exception)'
End If
Return types
End Function
Private Sub LoadDLLsThread(ByVal vObj As Object)
Dim objs As Object() = CType(vObj, Object())
Dim fileName As String = CStr(objs(0))
Dim globalTypes As List(Of Type) = CType(objs(1), Global.System.Collections.Generic.List(Of Global.System.Type))
Dim exceptions As List(Of Exception) = CType(objs(2), Global.System.Collections.Generic.List(Of Global.System.Exception))
Dim types As New List(Of Type)
Try
Dim myAssembly As Assembly = Assembly.LoadFrom(fileName)
For Each t In myAssembly.GetTypes()
If _typeToLoad.IsAssignableFrom(t) AndAlso _
t.IsClass = True AndAlso _
t.IsAbstract = False Then
types.Add(t)
End If
Next
SyncLock syncroot
globalTypes.AddRange(types)
End SyncLock
Catch ex As Exception
SyncLock syncroot
exceptions.Add(ex)
End SyncLock
End Try
End Sub
End Class
之后,使用 John Sibly 的答案动态创建任何类型的对象
干杯!