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

View file

@ -3,12 +3,12 @@
namespace Rai.PacketMediator; namespace Rai.PacketMediator;
[AttributeUsage(AttributeTargets.Class, Inherited = false)] [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; Code = code;
} }
public T Code { get; } public TPacketIdEnum Code { get; }
} }