I have packets :
public class HelloPacket
{
public string MyName { get; set; }
}
public class PingPacket
{
public float PingTime { get; set; }
}
I have a generic abstract 'handler' class like this :
public abstract class PacketHandler<T>
{
public abstract void Handle(T t);
}
And their implementations :
public class HelloPacketHandler : PacketHandler<HelloPacket>
{
public override void Handle(HelloPacket helloPacket)
{
Console.WriteLine("Received Hello packet!");
}
}
public class PingPacketHandler : PacketHandler<PingPacket>
{
public override void Handle(PingPacket pingPacket)
{
Console.WriteLine("Pong!");
}
}
I need to register them like this :
NetPacketProcessor _netPacketProcessor = new NetPacketProcessor();
HelloPacketHandler helloHandler = new HelloPacketHandler();
PingPacketHandler pingHandler = new PingPacketHandler();
_netPacketProcessor.SubscribeReusable<HelloPacket>((packet) => { helloHandler.Handle(packet); });
_netPacketProcessor.SubscribeReusable<PingPacket>((packet) => { pingHandler.Handle(packet); });
Here is the SubscribeReusable method :
public void SubscribeReusable<T>(Action<T> onReceive) where T : class, new()
{
}
The problem is that, as the solution grows, I will have to keep adding these calls.
I'm wondering if I could use reflection to dynamically call 'SubscribeReusable'. The problem I'm facing is with the generics.
Here is the code I started with :
foreach (Type i in typeof(PacketHandler).Assembly.GetTypes())
{
if (typeof(PacketHandler).IsAssignableFrom(i) && !i.IsAbstract && !i.IsInterface)
{
// Subscribe here
}
}
I tried Type and dynamic, but it is still not working. I'm wondering if I even have the right approach.
foreach (dynamic i in typeof(PacketHandler<dynamic>).Assembly.GetTypes())
{
if (typeof(PacketHandler<dynamic>).IsAssignableFrom(i) &&
!i.IsAbstract && !i.IsInterface)
{
PacketHandler<dynamic> pkt = (PacketHandler<dynamic>) Activator.CreateInstance(i);
Type t = pkt.GetType();
MethodInfo method = typeof(NetPacketProcessor).GetMethod(nameof(NetPacketProcessor.SubscribeReusable));
MethodInfo generic = method.MakeGenericMethod(t);
generic.Invoke(this, new object[]
{
pkt.Handle()
});
}
}
Aucun commentaire:
Enregistrer un commentaire