D
Dan Bass
VB.Net app, but applies to the C# articles I've seen (from Mr Skeet for
example) so decided to cross post to glean some more wisdom...
I've two instances of the plugin framework in my app for two separate
interfaces. One works and one doesn't, and for the life of my I can't figure
out the difference between them.
The one that works just fine:
IClient is the interface
DefaultClient is an abstract class whose parent is IClient (both
DefaultClient and IClient exist in IClient.DLL)
FileClient is a concrete class whose parent is DefaultClient. (FileClient
exists in FileClient.DLL)
I call this function from another application that references IClient to
dynamically load the plugin FileClient into an IClient referenced variable,
but this method resides in a singleton in IClient.DLL
Public Function Load(ByVal nameOfClient As String) As IClient
Dim asm As Assembly = Assembly.LoadFrom(nameOfClient + ".dll")
Dim ts As Type() = asm.GetTypes()
Dim t As Type = asm.GetType(_parentNamespace + nameOfClient, False,
True)
If (Not t Is Nothing) Then
Dim client As IClient = CType(Activator.CreateInstance(t),
IClient)
Return client
Else
Return Nothing
End If
End Function
The one that doesn't:
ITransform is the interface
TransformToXml is an abstract class whose parent is ITransform (both
TransformToXml and ITransform exist in ITransform.DLL)
PTXTransform is a concrete class whose parent is TransformToXml
(PTXTransform exists in PTXTransform.DLL)
I call this function from the same 3rd party app that also references
ITransfer (as well as IClient), and also resides in a singleton in
ITransform.DLL. When it gets to "CType(Activator.CreateInstance(t),
ITransform)", it fails with Invalid cast exception...
Public Function Load(ByVal nameOfTransform As String) As ITransform
Dim asm As Assembly = Assembly.LoadFrom(nameOfTransform + ".dll")
Dim ts As Type() = asm.GetTypes()
Dim t As Type = asm.GetType(_parentNamespace + nameOfTransform,
False, True)
If (Not t Is Nothing) Then
Dim trans As ITransform = CType(Activator.CreateInstance(t),
ITransform)
Return trans
Else
Return Nothing
End If
End Function
Now what comes to mind is that IClient is only working as a fluke, and
ITransform truly reflects my error, or I'm just missing something so simple
that I need to be shot. Below is the relevant implementation for the
classes/interfaces mentioned.
ITRANSFORM.DLL -----------------------------------------------------------------------------
Public Interface ITransform
Sub Initialise(Optional ByVal configurationFile As String = "")
Function Transform(ByVal source As String) As String
End Interface
Public MustInherit Class TransformToXml
Implements ITransform
Public MustOverride Sub Initialise(Optional ByVal configurationFile As
String = "") Implements ITransform.Initialise
Public MustOverride Function Transform(ByVal source As String) As String
Implements ITransform.Transform
Protected Function CreateSubXmlNode(ByVal doc As XmlDocument, ByVal
elementName As String, Optional ByVal elementContent As String = "") As
XmlNode
...
End Function
Protected Function XmlDocToString(ByVal xmlDoc As XmlDocument) As String
...
End Function
End Class
PTXTRANSFORM.DLL -----------------------------------------------------------------------------
Public Class PTXTransform
Inherits Olympus.GrapeVine.Transform.TransformToXml
Public Overrides Sub Initialise(Optional ByVal configurationFile As
String = "")
End Sub
Public Overrides Function Transform(ByVal source As String) As String
...
End Function
Private Function DecodeAudit(ByVal source As String()) As String
...
End Function
Private Function DecodeJob(ByVal source As String()) As String
...
End Function
Private Function DecodeWindow(ByVal source As String()) As String
...
End Function
Private Function DecodeMonitor(ByVal source As String()) As String
...
End Function
End Class
ICLIENT.DLL -----------------------------------------------------------------------------
Public Interface IClient
Property ClientName() As String
Sub Initialise(ByVal clientName As String, ByVal connectionString As
String)
Sub SendMessage(ByVal message As String)
Sub ReceiveMessage(ByRef message As String)
Function SupportedConnectionFields() As String
End Interface
Public MustInherit Class DefaultClient
Implements IClient
Protected _clientName As String
Public Property ClientName() As String Implements IClient.ClientName
Get
Return _clientName
End Get
Set(ByVal value As String)
_clientName = value
End Set
End Property
Public MustOverride Sub Initialise(ByVal clientName As String, ByVal
connectionString As String) Implements IClient.Initialise
Public MustOverride Sub ReceiveMessage(ByRef message As String)
Implements IClient.ReceiveMessage
Public MustOverride Sub SendMessage(ByVal message As String) Implements
IClient.SendMessage
Public MustOverride Function SupportedConnectionFields() As String
Implements IClient.SupportedConnectionFields
End Class
FILECLIENT.DLL -----------------------------------------------------------------------------
Public Class FileClient
Inherits Olympus.GrapeVine.Client.DefaultClient
Public Overrides Sub Initialise(ByVal clientName As String, ByVal
connectionString As String)
...
End Sub
Public Overrides Sub ReceiveMessage(ByRef message As String)
...
End Sub
Public Overrides Sub SendMessage(ByVal message As String)
...
End Sub
Public Overrides Function SupportedConnectionFields() As String
...
End Function
End Class
example) so decided to cross post to glean some more wisdom...
I've two instances of the plugin framework in my app for two separate
interfaces. One works and one doesn't, and for the life of my I can't figure
out the difference between them.
The one that works just fine:
IClient is the interface
DefaultClient is an abstract class whose parent is IClient (both
DefaultClient and IClient exist in IClient.DLL)
FileClient is a concrete class whose parent is DefaultClient. (FileClient
exists in FileClient.DLL)
I call this function from another application that references IClient to
dynamically load the plugin FileClient into an IClient referenced variable,
but this method resides in a singleton in IClient.DLL
Public Function Load(ByVal nameOfClient As String) As IClient
Dim asm As Assembly = Assembly.LoadFrom(nameOfClient + ".dll")
Dim ts As Type() = asm.GetTypes()
Dim t As Type = asm.GetType(_parentNamespace + nameOfClient, False,
True)
If (Not t Is Nothing) Then
Dim client As IClient = CType(Activator.CreateInstance(t),
IClient)
Return client
Else
Return Nothing
End If
End Function
The one that doesn't:
ITransform is the interface
TransformToXml is an abstract class whose parent is ITransform (both
TransformToXml and ITransform exist in ITransform.DLL)
PTXTransform is a concrete class whose parent is TransformToXml
(PTXTransform exists in PTXTransform.DLL)
I call this function from the same 3rd party app that also references
ITransfer (as well as IClient), and also resides in a singleton in
ITransform.DLL. When it gets to "CType(Activator.CreateInstance(t),
ITransform)", it fails with Invalid cast exception...
Public Function Load(ByVal nameOfTransform As String) As ITransform
Dim asm As Assembly = Assembly.LoadFrom(nameOfTransform + ".dll")
Dim ts As Type() = asm.GetTypes()
Dim t As Type = asm.GetType(_parentNamespace + nameOfTransform,
False, True)
If (Not t Is Nothing) Then
Dim trans As ITransform = CType(Activator.CreateInstance(t),
ITransform)
Return trans
Else
Return Nothing
End If
End Function
Now what comes to mind is that IClient is only working as a fluke, and
ITransform truly reflects my error, or I'm just missing something so simple
that I need to be shot. Below is the relevant implementation for the
classes/interfaces mentioned.
ITRANSFORM.DLL -----------------------------------------------------------------------------
Public Interface ITransform
Sub Initialise(Optional ByVal configurationFile As String = "")
Function Transform(ByVal source As String) As String
End Interface
Public MustInherit Class TransformToXml
Implements ITransform
Public MustOverride Sub Initialise(Optional ByVal configurationFile As
String = "") Implements ITransform.Initialise
Public MustOverride Function Transform(ByVal source As String) As String
Implements ITransform.Transform
Protected Function CreateSubXmlNode(ByVal doc As XmlDocument, ByVal
elementName As String, Optional ByVal elementContent As String = "") As
XmlNode
...
End Function
Protected Function XmlDocToString(ByVal xmlDoc As XmlDocument) As String
...
End Function
End Class
PTXTRANSFORM.DLL -----------------------------------------------------------------------------
Public Class PTXTransform
Inherits Olympus.GrapeVine.Transform.TransformToXml
Public Overrides Sub Initialise(Optional ByVal configurationFile As
String = "")
End Sub
Public Overrides Function Transform(ByVal source As String) As String
...
End Function
Private Function DecodeAudit(ByVal source As String()) As String
...
End Function
Private Function DecodeJob(ByVal source As String()) As String
...
End Function
Private Function DecodeWindow(ByVal source As String()) As String
...
End Function
Private Function DecodeMonitor(ByVal source As String()) As String
...
End Function
End Class
ICLIENT.DLL -----------------------------------------------------------------------------
Public Interface IClient
Property ClientName() As String
Sub Initialise(ByVal clientName As String, ByVal connectionString As
String)
Sub SendMessage(ByVal message As String)
Sub ReceiveMessage(ByRef message As String)
Function SupportedConnectionFields() As String
End Interface
Public MustInherit Class DefaultClient
Implements IClient
Protected _clientName As String
Public Property ClientName() As String Implements IClient.ClientName
Get
Return _clientName
End Get
Set(ByVal value As String)
_clientName = value
End Set
End Property
Public MustOverride Sub Initialise(ByVal clientName As String, ByVal
connectionString As String) Implements IClient.Initialise
Public MustOverride Sub ReceiveMessage(ByRef message As String)
Implements IClient.ReceiveMessage
Public MustOverride Sub SendMessage(ByVal message As String) Implements
IClient.SendMessage
Public MustOverride Function SupportedConnectionFields() As String
Implements IClient.SupportedConnectionFields
End Class
FILECLIENT.DLL -----------------------------------------------------------------------------
Public Class FileClient
Inherits Olympus.GrapeVine.Client.DefaultClient
Public Overrides Sub Initialise(ByVal clientName As String, ByVal
connectionString As String)
...
End Sub
Public Overrides Sub ReceiveMessage(ByRef message As String)
...
End Sub
Public Overrides Sub SendMessage(ByVal message As String)
...
End Sub
Public Overrides Function SupportedConnectionFields() As String
...
End Function
End Class