A Packets/NosSmooth.PacketSerializer/Extensions/PacketTypesRepositoryExtensions.cs => Packets/NosSmooth.PacketSerializer/Extensions/PacketTypesRepositoryExtensions.cs +42 -0
@@ 0,0 1,42 @@
+//
+// PacketTypesRepositoryExtensions.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Linq;
+using System.Reflection;
+using NosSmooth.Packets.Packets;
+using Remora.Results;
+
+namespace NosSmooth.Packets.Extensions;
+
+/// <summary>
+/// Extension methods for <see cref="IPacketTypesRepository"/>.
+/// </summary>
+public static class PacketTypesRepositoryExtensions
+{
+ /// <summary>
+ /// Add packets from the given assembly.
+ /// </summary>
+ /// <param name="packetTypesRepository">The packet types repository.</param>
+ /// <param name="assembly">The assembly to add packets from.</param>
+ /// <returns>A result that may or may not have succeeded.</returns>
+ public static Result AddPacketTypes(this IPacketTypesRepository packetTypesRepository, Assembly assembly)
+ {
+ var packetTypes = assembly
+ .GetExportedTypes()
+ .Where(x => x != typeof(UnresolvedPacket) && !x.IsAbstract && typeof(IPacket).IsAssignableFrom(x));
+ return packetTypesRepository.AddPacketTypes(packetTypes);
+ }
+
+ /// <summary>
+ /// Adds the default NosSmooth packets.
+ /// </summary>
+ /// <param name="packetTypesRepository">The packet types repository.</param>
+ /// <returns>A result tht may or may not have succeeded.</returns>
+ public static Result AddDefaultPackets(this IPacketTypesRepository packetTypesRepository)
+ {
+ return packetTypesRepository.AddPacketTypes(typeof(IPacket).Assembly);
+ }
+}<
\ No newline at end of file
M Packets/NosSmooth.PacketSerializer/Extensions/ServiceCollectionExtensions.cs => Packets/NosSmooth.PacketSerializer/Extensions/ServiceCollectionExtensions.cs +1 -18
@@ 38,24 38,7 @@ public static class ServiceCollectionExtensions
.AddSingleton<IStringConverterRepository, StringConverterRepository>()
.AddSingleton<IStringSerializer, StringSerializer>()
.AddSingleton<IPacketSerializer, PacketSerializer>()
- .AddSingleton<IPacketTypesRepository>(p =>
- {
- var repository = new PacketTypesRepository(p.GetRequiredService<IStringConverterRepository>());
- var packetTypes = typeof(IPacket).Assembly
- .GetExportedTypes()
- .Where(x => x != typeof(UnresolvedPacket) && !x.IsAbstract && typeof(IPacket).IsAssignableFrom(x));
- foreach (var packetType in packetTypes)
- {
- var result = repository.AddPacketType(packetType);
- if (!result.IsSuccess)
- {
- // TODO: figure out how to handle this.
- throw new Exception(packetType + ": " + result.Error.Message);
- }
- }
-
- return repository;
- })
+ .AddSingleton<IPacketTypesRepository, PacketTypesRepository>()
.AddGeneratedSerializers(typeof(IPacket).Assembly)
.AddBasicConverters();
}
M Packets/NosSmooth.PacketSerializer/Packets/IPacketTypesRepository.cs => Packets/NosSmooth.PacketSerializer/Packets/IPacketTypesRepository.cs +13 -0
@@ 26,6 26,19 @@ public interface IPacketTypesRepository
public Result AddPacketType(Type type);
/// <summary>
+ /// Add all of the given packet types.
+ /// </summary>
+ /// <remarks>
+ /// If there is an error, it will continue to add the rest of the types
+ /// and then return an aggregate error containing all the errors.
+ ///
+ /// The application can still run, but without the errorful packets.
+ /// </remarks>
+ /// <param name="packetTypes">The types add.</param>
+ /// <returns>A result that may or may not have succeeded.</returns>
+ public Result AddPacketTypes(IEnumerable<Type> packetTypes);
+
+ /// <summary>
/// Gets the type of a packet that corresponds to the given header.
/// </summary>
/// <param name="header">The header of the packet.</param>
M Packets/NosSmooth.PacketSerializer/Packets/PacketTypesRepository.cs => Packets/NosSmooth.PacketSerializer/Packets/PacketTypesRepository.cs +25 -3
@@ 46,13 46,13 @@ public class PacketTypesRepository : IPacketTypesRepository
{
if (!typeof(IPacket).IsAssignableFrom(type))
{
- return new ArgumentInvalidError(nameof(type), "The type has to be assignable to IPacket.");
+ return new ArgumentInvalidError(nameof(type), $"The type has to be assignable to IPacket. {type.FullName} isn't.");
}
var header = type.GetCustomAttribute<PacketHeaderAttribute>();
if (header is null)
{
- return new ArgumentInvalidError(nameof(type), "Every packet has to specify the header.");
+ return new ArgumentInvalidError(nameof(type), $"Every packet has to specify the header. {type.FullName} didn't.");
}
var converterResult = _stringConverterRepository.GetTypeConverter(type);
@@ 91,6 91,27 @@ public class PacketTypesRepository : IPacketTypesRepository
return Result.FromSuccess();
}
+ /// <inheritdoc />
+ public Result AddPacketTypes(IEnumerable<Type> packetTypes)
+ {
+ var errorResults = new List<IResult>();
+ foreach (var packetType in packetTypes)
+ {
+ var result = AddPacketType(packetType);
+ if (!result.IsSuccess)
+ {
+ errorResults.Add(result);
+ }
+ }
+
+ return errorResults.Count switch
+ {
+ 0 => Result.FromSuccess(),
+ 1 => (Result)errorResults[0],
+ _ => new AggregateError(errorResults)
+ };
+ }
+
/// <summary>
/// Gets the type of a packet that corresponds to the given header.
/// </summary>
@@ 133,7 154,8 @@ public class PacketTypesRepository : IPacketTypesRepository
/// </summary>
/// <typeparam name="TPacket">The type of the packet.</typeparam>
/// <returns>Info that stores the packet's info. Or an error, if not found.</returns>
- public Result<PacketInfo> FindPacketInfo<TPacket>() where TPacket : IPacket
+ public Result<PacketInfo> FindPacketInfo<TPacket>()
+ where TPacket : IPacket
=> FindPacketInfo(typeof(TPacket));
/// <summary>