我想寫一些代碼,這將允許我動態加載DLL到我的應用程序,具體取決於應用程序設置。這個想法是,要訪問的數據庫在應用程序設置中設置,然後加載適當的DLL並將其分配給接口的實例,供我的應用程序訪問。.Net動態加載DLL
這是我的時刻代碼:
Dim SQLDataSource As ICRDataLayer
Dim ass As Assembly = Assembly. _
LoadFrom("M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\SQLServer.dll")
Dim obj As Object = ass.CreateInstance(GetType(ICRDataLayer).ToString, True)
SQLDataSource = DirectCast(obj, ICRDataLayer)
MsgBox(SQLDataSource.ModuleName & vbNewLine & SQLDataSource.ModuleDescription)
我有我的接口(ICRDataLayer)和SQLServer.dll包含此接口的實現。我只想加載程序集並將其分配給SQLDataSource對象。
上述代碼不起作用。沒有例外拋出,即使Msgbox沒有出現。 我會期望至少該消息框沒有任何內容出現,但即使這樣也不會發生!
有沒有一種方法來確定加載的程序集是否實現了特定的接口。我嘗試了下面的內容,但這似乎也沒有做任何事情!
For Each loadedType As Type In ass.GetTypes
If GetType(ICRDataLayer).IsAssignableFrom(loadedType) Then
Dim obj1 As Object = ass.CreateInstance(GetType(ICRDataLayer).ToString, True)
SQLDataSource = DirectCast(obj1, ICRDataLayer)
End If
Next
編輯:從弗拉德的例子新的代碼:
Module CRDataLayerFactory
Sub New()
End Sub
' class name is a contract,
' should be the same for all plugins
Private Function Create() As ICRDataLayer
Return New SQLServer()
End Function
End Module
以上是在每個DLL,從弗拉德的C#示例轉換模塊。
下面是我的代碼在DLL帶來:
Dim SQLDataSource As ICRDataLayer
Dim ass As Assembly = Assembly. _
LoadFrom("M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\SQLServer.dll")
Dim factory As Object = ass.CreateInstance("CRDataLayerFactory", True)
Dim t As Type = factory.GetType
Dim method As MethodInfo = t.GetMethod("Create")
Dim obj As Object = method.Invoke(factory, Nothing)
SQLDataSource = DirectCast(obj, ICRDataLayer)
編輯:實現基於保羅·科勒的代碼
Dim file As String
For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
Dim assemblyType As System.Type
For Each assemblyType In Assembly.LoadFrom(file).GetTypes
Dim s As System.Type() = assemblyType.GetInterfaces
For Each ty As System.Type In s
If ty.Name.Contains("ICRDataLayer") Then
MsgBox(ty.Name)
plugin = DirectCast(Activator.CreateInstance(assemblyType), ICRDataLayer)
MessageBox.Show(plugin.ModuleName)
End If
Next
我得到這個代碼以下錯誤:
無法投射'SQLServer.CR'類型的對象DataSource.SQLServer'鍵入'DynamicAssemblyLoading.ICRDataLayer'。
實際的DLL位於與我的實現代碼相同的解決方案中的另一個名爲SQLServer的項目中。 CRDataSource是一個名稱空間,SQLServer是該DLL的實際類名稱。 SQLServer類實現ICRDataLayer,所以我不明白爲什麼它無法投射它。 這裏的命名很重要,我不會想到它會是。 PluginUtility的
最後的工作代碼
內容:
enter code here Public Shared Function GetInstances1(Of Type)(ByVal baseDir As String, ByVal searchPattern As String) As System.Type()
Dim tmpInstances As New List(Of Type)
Try
Dim file As String
For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
Dim assemblyType As System.Type
For Each assemblyType In Assembly.LoadFrom(file).GetTypes
Dim s As System.Type() = assemblyType.GetInterfaces
Return s.ToArray()
Next
Next
Catch exp As TargetInvocationException
If (Not exp.InnerException Is Nothing) Then
Throw exp.InnerException
End If
End Try
End Function
代碼加載DLL:
enter code here
Dim basedir As String = "M:\MyProgs\WebService\DynamicAssemblyLoading\SQLServer\bin\Debug\"
Dim searchPattern As String = "*SQL*.dll"
Dim plugin As CRDataLayer.ICRDataLayer
Try
Dim file As String
For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
Dim assemblyType As System.Type
For Each assemblyType In Assembly.LoadFrom(file).GetExportedTypes
If assemblyType.GetInterface("CRDataLayer.ICRDataLayer") IsNot Nothing Then
plugin = DirectCast(Activator.CreateInstance(assemblyType), CRDataLayer.ICRDataLayer)
MessageBox.Show(plugin.ModuleDescription)
End If
Next
Next
Catch exp As TargetInvocationException
If (Not exp.InnerException Is Nothing) Then
Throw exp.InnerException
End If
Catch ex As Exception
MsgBox(ex.Message)
Clipboard.SetText(ex.Message)
End Try
不要使用'ty.Name.Contains( 「ICRDataLayer」)' - 檢查它 「實現類型」 與'assemblyType.GetInterface( 「命名空間etc.ICRDataLayer」) '(seehttp://msdn.microsoft.com/en-us/library/tcctb9t8.aspx)如果它沒有被當前類型實現,它會給你'Nothing'。此外,異常似乎表明接口未實現,您是否使用共享DLL - 它需要是同一個DLL。 PK – 2010-03-08 23:51:21
再次檢查下面的解決方案... – 2010-03-09 03:00:13
它的工作原理! 我最終使用了你的代碼Paul,它的工作原理與我需要的完全一樣。 對於任何未來可能會遇到此線程的人,我會將我的最終代碼添加到原始帖子中,希望他們能夠比我更容易地使用它。 謝謝你的幫助 – hermiod 2010-03-10 23:44:27