I’m building a series of classes in an attempt to reduce the manual coding of specific class types from the mainline code.
Whichever way I look there is always somewhere that requires manual coding of the specific class type.
I was hoping that I could use reflection/activator etc to be able to use the work done in the constructor to be able to return the classtypes (of the correct type) without needing to do the large (although the example here has been reduced) select/switch statement that is in GetPacket.
I know this is VB.Net, but the project was already written in that language, I don’t mind if you post C# examples I’ll just convert them.
But please don’t retag as a VB.Net question because it’s not about language it’s about how to do it within the framework.
Imports ProtoBuf
Public Class CompatiblePackets
Inherits Dictionary(Of Packet.PacketType, Base)
Public Sub New()
Dim theAssembly As Assembly = Assembly.GetExecutingAssembly
For Each t As Type In theAssembly.GetTypes
If t.BaseType Is GetType(Base) Then
Dim p As Base = CType(t.Assembly.CreateInstance(t.FullName), Base)
Me.Add(p.PacketTypeIndicator, p)
End If
Next
End Sub
Public Function GetPacket(id As PacketType, data As Stream) As Base
Dim activePacket As Base
If Me.ContainsKey(id) Then
activePacket = Me(id)
Else
activePacket = Me(PacketType.Generic)
End If
Try
Select Case id
Case PacketType.AcknowledgeBulk
Return GetPacket(Of AcknowledgeBulk)(activePacket, data)
Case PacketType.Generic
Return GetPacket(Of Generic)(activePacket, data)
Case PacketType.Identification
Return GetPacket(Of Identification)(activePacket, data)
'''There are so far about 20 more packet types in the real code.
Case Else
'unknown type "Computer says No!"
End Select
Catch ex As Exception
If data.GetType Is GetType(MemoryStream) Then
Debug.Print(Core.Text.OutputData(CType(data, MemoryStream).ToArray))
End If
Throw
End Try
Debug.Print("Wtf - " & id.ToString())
Return New NoOperation
End Function
Private Function GetPacket(Of t)(activePacket As Packet.Base, data As Stream) As t
Return Serializer.Deserialize(Of t)(data)
End Function
End Class
If I understand the question correctly, it looks like you should be using
Serializer.NonGeneric; this has various methods for passing theTypein manually and without using generics, includingSerializeandDeserialize.Note that for this scenario,
Serializer.NonGenericalso has a specific API for heterogeneous header-marked messages, which you may find useful for a network-stream scenario:This outputs:
In v2, note that
TypeModelexposes the non-generic API as the primary interface (theSerializerAPI simply acts as a proxy to the default model).