her*_*iod 8 vb.net reflection dll assemblies
我试图编写一些代码,允许我动态地将DLL加载到我的应用程序中,具体取决于应用程序设置.我们的想法是在应用程序设置中设置要访问的数据库,然后加载相应的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)
Run Code Online (Sandbox Code Playgroud)
我有我的接口(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
Run Code Online (Sandbox Code Playgroud)
编辑:Vlad的例子中的新代码:
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
Run Code Online (Sandbox Code Playgroud)
上面是每个DLL中的Module,从Vlad的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)
Run Code Online (Sandbox Code Playgroud)
编辑:基于Paul Kohler的代码实现
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
Run Code Online (Sandbox Code Playgroud)
我用以下代码得到以下错误:
无法将类型为"SQLServer.CRDataSource.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
Run Code Online (Sandbox Code Playgroud)
加载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
Run Code Online (Sandbox Code Playgroud)
版本 2 - 该示例从当前目录加载 DLL。有 2 个项目,1 个控制台应用程序项目和一个“模块”项目(模块将其 DLL“复制”到控制台应用程序的工作目录)。
下面的示例简单演示了动态加载实现接口的 DLL。该IModule接口仅报告其名称。将创建当前目录中以“.Module.dll”结尾的 DLL 中找到的PlugInUtility.GetInstances(Of IModule)(Environment.CurrentDirectory, "*.Module.dll")任何实例的实例。IModule它是直接从 Mini SQL 查询中反映出来的 VB.NET 版本。
考虑到这一点,例如:
Dim modules As IModule() = PlugInUtility.GetInstances(Of ICRDataLayer)(Environment.CurrentDirectory, "*.Server.dll")
Run Code Online (Sandbox Code Playgroud)
应该可以满足你的要求。然后你只需要选择执行哪一个即可!
代码:
在“VB.LoaderDemo Colsole应用程序”中
' IModule.vb
Public Interface IModule
Property ModuleName() As String
End Interface
' PlugInUtility.vb
Imports System.IO
Imports System.Reflection
Public Class PlugInUtility
Public Shared Function GetInstances(Of T)(ByVal baseDir As String, ByVal searchPattern As String) As T()
Dim tmpInstances As New List(Of T)
Try
Dim file As String
For Each file In Directory.GetFiles(baseDir, searchPattern, SearchOption.TopDirectoryOnly)
Dim assemblyType As Type
For Each assemblyType In Assembly.LoadFrom(file).GetTypes()
If (Not assemblyType.GetInterface(GetType(T).FullName) Is Nothing) Then
tmpInstances.Add(DirectCast(Activator.CreateInstance(assemblyType), T))
End If
Next
Next
Catch exp As TargetInvocationException
If (Not exp.InnerException Is Nothing) Then
Throw exp.InnerException
End If
End Try
Return tmpInstances.ToArray()
End Function
End Class
' MainModule.vb
Module MainModule
Sub Main()
Dim plugins As IModule() = PlugInUtility.GetInstances(Of IModule)(Environment.CurrentDirectory, "*.Module.dll")
Dim m As IModule
For Each m In plugins
Console.WriteLine(m.ModuleName)
Next
End Sub
End Module
Run Code Online (Sandbox Code Playgroud)
在“Sample1 DLL”中(IModule 引用“VB.LoaderDemo”)
Imports VB.LoaderDemo
Public Class MyModule1
Implements IModule
Dim _name As String
Public Sub New()
_name = "Sample 1, Module 1"
End Sub
Public Property ModuleName() As String Implements IModule.ModuleName
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class
Run Code Online (Sandbox Code Playgroud)
输出是:
> Sample 1, Module 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20497 次 |
| 最近记录: |