chore: explicit generic Types

This commit is contained in:
Timothy Schenk 2024-02-05 10:43:04 +01:00
parent 1668f0f73d
commit bae1f812cf
Signed by: rainote
SSH key fingerprint: SHA256:pnkNSDwpAnaip00xaZlVFHKKsS7T8UtOomMzvs0yITE
3 changed files with 26 additions and 26 deletions

View file

@ -6,14 +6,14 @@ using JetBrains.Annotations;
namespace Rai.PacketMediator;
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public interface IPacketHandler<in T, in S> : IPacketHandler<S> where T : IIncomingPacket
public interface IPacketHandler<in TIncomingPacket, in TSession> : IPacketHandler<TSession> where TIncomingPacket : IIncomingPacket
{
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public Task HandleAsync(T packet, S session);
public Task HandleAsync(TIncomingPacket packet, TSession session);
async Task<bool> IPacketHandler<S>.TryHandleAsync(IIncomingPacket packet, S session)
async Task<bool> IPacketHandler<TSession>.TryHandleAsync(IIncomingPacket packet, TSession session)
{
if (packet is not T tPacket)
if (packet is not TIncomingPacket tPacket)
{
return false;
}
@ -27,7 +27,7 @@ public interface IPacketHandler<in T, in S> : IPacketHandler<S> where T : IIncom
}
}
public interface IPacketHandler<in S>
public interface IPacketHandler<in TSession>
{
Task<bool> TryHandleAsync(IIncomingPacket packet, S session);
Task<bool> TryHandleAsync(IIncomingPacket packet, TSession session);
}

View file

@ -15,35 +15,35 @@ namespace Rai.PacketMediator;
using static CodeGenerator;
public class PacketDistributorService<T, S> : Microsoft.Extensions.Hosting.IHostedService, IDisposable where T : Enum
public class PacketDistributorService<TPacketIdEnum, TSession> : Microsoft.Extensions.Hosting.IHostedService, IDisposable where TPacketIdEnum : Enum
{
private readonly Channel<ValueTuple<byte[], T, S>> _channel;
private readonly Channel<ValueTuple<byte[], TPacketIdEnum, TSession>> _channel;
private readonly IServiceProvider _serviceProvider;
private readonly Assembly[] _sourcesContainingPackets;
private ImmutableDictionary<T,
private ImmutableDictionary<TPacketIdEnum,
Func<byte[], IIncomingPacket>> _deserializationMap;
private ConcurrentDictionary<T, IPacketHandler<S>?> _packetHandlersInstantiation;
private ConcurrentDictionary<TPacketIdEnum, IPacketHandler<TSession>?> _packetHandlersInstantiation;
private readonly ActivitySource _activitySource;
public PacketDistributorService(IServiceProvider serviceProvider,
Assembly[] sourcesContainingPackets)
{
_channel = Channel.CreateUnbounded<ValueTuple<byte[], T, S>>();
_channel = Channel.CreateUnbounded<ValueTuple<byte[], TPacketIdEnum, TSession>>();
_serviceProvider = serviceProvider;
_sourcesContainingPackets = sourcesContainingPackets;
_activitySource = new ActivitySource(nameof(PacketMediator));
}
private Dictionary<T, Type> RetrievePacketsDictionary()
private Dictionary<TPacketIdEnum, Type> RetrievePacketsDictionary()
{
using var activity = this._activitySource.StartActivity();
var packetsWithId = this._sourcesContainingPackets.SelectMany(a => a.GetTypes()
.Where(type => type is { IsInterface: false, IsAbstract: false } &&
type.GetInterfaces().Contains(typeof(IIncomingPacket)))
.Select(type => new { Type = type, Attribute = type.GetCustomAttribute<PacketIdAttribute<T>>() })
.Select(type => new { Type = type, Attribute = type.GetCustomAttribute<PacketIdAttribute<TPacketIdEnum>>() })
.Where(item => item.Attribute is not null)
.ToDictionary(item => item.Attribute!.Code, item => item.Type)).ToDictionary();
@ -52,22 +52,22 @@ public class PacketDistributorService<T, S> : Microsoft.Extensions.Hosting.IHost
return packetsWithId;
}
private Dictionary<T, Type> GetAllPacketHandlersWithId()
private Dictionary<TPacketIdEnum, Type> GetAllPacketHandlersWithId()
{
using var activity = this._activitySource.StartActivity();
var packetHandlersWithId = this._sourcesContainingPackets.SelectMany(assembly => assembly.GetTypes()
.Where(t =>
t is { IsClass: true, IsAbstract: false } && Array.Exists(t
.GetInterfaces(), i =>
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<S>)))
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<TSession>)))
.Select(type => new
{
Type = type,
PacketId = type
.GetInterfaces().First(t1 =>
t1 is { IsGenericType: true } && t1.GetGenericTypeDefinition() == typeof(IPacketHandler<S>))
.GetGenericArguments().First(t => t.GetCustomAttributes<PacketIdAttribute<T>>().Any())
.GetCustomAttributes<PacketIdAttribute<T>>().First().Code
t1 is { IsGenericType: true } && t1.GetGenericTypeDefinition() == typeof(IPacketHandler<TSession>))
.GetGenericArguments().First(t => t.GetCustomAttributes<PacketIdAttribute<TPacketIdEnum>>().Any())
.GetCustomAttributes<PacketIdAttribute<TPacketIdEnum>>().First().Code
})
.ToDictionary(
x => x.PacketId, x => x.Type
@ -99,14 +99,14 @@ public class PacketDistributorService<T, S> : Microsoft.Extensions.Hosting.IHost
}
var tempDeserializationMap =
new Dictionary<T, Func<byte[], IIncomingPacket>>();
_packetHandlersInstantiation = new ConcurrentDictionary<T, IPacketHandler<S>?>();
new Dictionary<TPacketIdEnum, Func<byte[], IIncomingPacket>>();
_packetHandlersInstantiation = new ConcurrentDictionary<TPacketIdEnum, IPacketHandler<TSession>?>();
packetHandlers.ForEach(x =>
{
var packetHandler =
ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider,
x.Value);
_packetHandlersInstantiation.TryAdd(x.Key, packetHandler as IPacketHandler<S>);
_packetHandlersInstantiation.TryAdd(x.Key, packetHandler as IPacketHandler<TSession>);
});
foreach (var packetsType in packetDictionary)
{
@ -130,7 +130,7 @@ public class PacketDistributorService<T, S> : Microsoft.Extensions.Hosting.IHost
return Task.CompletedTask;
}
public async Task AddPacketAsync(byte[] packetData, T operationCode, S session)
public async Task AddPacketAsync(byte[] packetData, TPacketIdEnum operationCode, TSession session)
{
await _channel.Writer.WriteAsync((packetData, operationCode, session));
}
@ -146,7 +146,7 @@ public class PacketDistributorService<T, S> : Microsoft.Extensions.Hosting.IHost
}
}
private async Task InvokePacketHandlerAsync((byte[], T, S) valueTuple)
private async Task InvokePacketHandlerAsync((byte[], TPacketIdEnum, TSession) valueTuple)
{
IIncomingPacket packet;
var (packetData, operationCode, session) = valueTuple;

View file

@ -3,12 +3,12 @@
namespace Rai.PacketMediator;
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public abstract class PacketIdAttribute<T> : Attribute where T : Enum
public abstract class PacketIdAttribute<TPacketIdEnum> : Attribute where TPacketIdEnum : Enum
{
protected PacketIdAttribute(T code)
protected PacketIdAttribute(TPacketIdEnum code)
{
Code = code;
}
public T Code { get; }
public TPacketIdEnum Code { get; }
}