diff --git a/src/BootstrapBlazor/Extensions/ITcpSocketClientExtensions.cs b/src/BootstrapBlazor/Extensions/ITcpSocketClientExtensions.cs
index cf58a2b31ad..feafc612089 100644
--- a/src/BootstrapBlazor/Extensions/ITcpSocketClientExtensions.cs
+++ b/src/BootstrapBlazor/Extensions/ITcpSocketClientExtensions.cs
@@ -76,20 +76,18 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPack
}
///
- /// Configures the specified to use a custom data package adapter and a callback
- /// function for processing received data.
+ /// Configures the specified to use a data package adapter and a callback function
+ /// for processing received data.
///
- /// This method sets up the to use the provided for handling incoming data. The adapter processes the raw data received by the client and
- /// attempts to convert it into an instance of . If the conversion is successful, the
- /// is invoked with the converted entity; otherwise, it is invoked with .
- /// The type of the entity that the data package adapter will attempt to convert the received data into.
- /// The instance to configure.
- /// The instance responsible for handling and processing incoming data.
- /// A callback function to be invoked with the processed data of type . The callback
- /// receives if the data cannot be converted to .
- public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, Func callback)
+ /// This method sets up the to process incoming data using the
+ /// specified and . The is called with the converted entity whenever data is received.
+ /// The type of the entity that the data will be converted to.
+ /// The TCP socket client to configure.
+ /// The data package adapter responsible for handling incoming data.
+ /// The converter used to transform the received data into the specified entity type.
+ /// The callback function to be invoked with the converted entity.
+ public static void SetDataPackageAdapter(this ITcpSocketClient client, IDataPackageAdapter adapter, ISocketDataConverter socketDataConverter, Func callback)
{
// 设置 ITcpSocketClient 的回调函数
client.ReceivedCallBack = async buffer =>
@@ -102,12 +100,9 @@ public static void SetDataPackageAdapter(this ITcpSocketClient client,
adapter.ReceivedCallBack = async buffer =>
{
TEntity? ret = default;
- if (adapter.TryConvertTo(buffer, out var t))
+ if (socketDataConverter.TryConvertTo(buffer, out var t))
{
- if (t is TEntity entity)
- {
- ret = entity;
- }
+ ret = t;
}
await callback(ret);
};
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataConverter/ISocketDataConverter.cs b/src/BootstrapBlazor/Services/TcpSocket/DataConverter/ISocketDataConverter.cs
new file mode 100644
index 00000000000..1d5f3f6b0d7
--- /dev/null
+++ b/src/BootstrapBlazor/Services/TcpSocket/DataConverter/ISocketDataConverter.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License
+// See the LICENSE file in the project root for more information.
+// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
+
+namespace BootstrapBlazor.Components;
+
+///
+/// Defines a method to convert raw socket data into a specified entity type.
+///
+/// The type of entity to convert the data into.
+public interface ISocketDataConverter
+{
+ ///
+ /// Attempts to convert the specified data to an instance of .
+ ///
+ /// This method does not throw an exception if the conversion fails. Instead, it returns and sets to .
+ /// The data to be converted, represented as a read-only memory block of bytes.
+ /// When this method returns, contains the converted if the conversion succeeded;
+ /// otherwise, .
+ /// if the conversion was successful; otherwise, .
+ bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out TEntity? entity);
+}
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataConverter/SocketDataConverterBase.cs b/src/BootstrapBlazor/Services/TcpSocket/DataConverter/SocketDataConverterBase.cs
new file mode 100644
index 00000000000..2375587a94c
--- /dev/null
+++ b/src/BootstrapBlazor/Services/TcpSocket/DataConverter/SocketDataConverterBase.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License
+// See the LICENSE file in the project root for more information.
+// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
+
+namespace BootstrapBlazor.Components;
+
+///
+/// Provides a base class for converting socket data into a specified entity type.
+///
+/// The type of entity to convert the socket data into.
+public abstract class SocketDataConverterBase : ISocketDataConverter
+{
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public abstract bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out TEntity? entity);
+}
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/DataPackageAdapter.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/DataPackageAdapter.cs
index a1b7e98e940..77733014514 100644
--- a/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/DataPackageAdapter.cs
+++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/DataPackageAdapter.cs
@@ -48,12 +48,18 @@ public virtual async ValueTask HandlerAsync(ReadOnlyMemory data, Cancellat
///
///
///
+ ///
///
///
- public virtual bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out object? entity)
+ public virtual bool TryConvertTo(ReadOnlyMemory data, ISocketDataConverter socketDataConverter, out TEntity? entity)
{
- entity = null;
- return false;
+ entity = default;
+ var ret = socketDataConverter.TryConvertTo(data, out var v);
+ if (ret)
+ {
+ entity = v;
+ }
+ return ret;
}
///
diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/IDataPackageAdapter.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/IDataPackageAdapter.cs
index f603c528460..e37d9272495 100644
--- a/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/IDataPackageAdapter.cs
+++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackageAdapter/IDataPackageAdapter.cs
@@ -41,13 +41,15 @@ public interface IDataPackageAdapter
ValueTask HandlerAsync(ReadOnlyMemory data, CancellationToken token = default);
///
- /// Attempts to convert the specified binary data into an object representation.
+ /// Attempts to convert the specified byte data into an entity of type .
///
- /// This method does not throw an exception if the conversion fails. Instead, it returns and sets to .
- /// The binary data to be converted. Must not be empty.
- /// When this method returns , contains the converted object. When this method returns , contains .
+ /// This method does not throw an exception if the conversion fails. Instead, it returns and sets to its default value.
+ /// The type of the entity to convert the data to.
+ /// The byte data to be converted.
+ /// The converter used to transform the byte data into an entity.
+ /// When this method returns, contains the converted entity if the conversion was successful; otherwise, the default
+ /// value for the type of the entity.
/// if the conversion was successful; otherwise, .
- bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out object? entity);
+ bool TryConvertTo(ReadOnlyMemory data, ISocketDataConverter socketDataConverter, out TEntity? entity);
}
diff --git a/test/UnitTest/Services/TcpSocketFactoryTest.cs b/test/UnitTest/Services/TcpSocketFactoryTest.cs
index b552daedf06..72bab657d70 100644
--- a/test/UnitTest/Services/TcpSocketFactoryTest.cs
+++ b/test/UnitTest/Services/TcpSocketFactoryTest.cs
@@ -651,11 +651,11 @@ public async Task TryConvertTo_Ok()
MockEntity? entity = null;
// 设置数据适配器
- var adapter = new MockEntityDataPackageAdapter
+ var adapter = new DataPackageAdapter
{
DataPackageHandler = new FixLengthDataPackageHandler(7),
};
- client.SetDataPackageAdapter(adapter, t =>
+ client.SetDataPackageAdapter(adapter, new MockEntitySocketDataConverter(), t =>
{
entity = t;
tcs.SetResult();
@@ -676,9 +676,10 @@ public async Task TryConvertTo_Ok()
// 测试异常流程
var adapter2 = new DataPackageAdapter();
- var result = adapter2.TryConvertTo(data, out var t);
- Assert.False(result);
- Assert.Null(t);
+ var result = adapter2.TryConvertTo(data, new MockEntitySocketDataConverter(), out var t);
+ Assert.True(result);
+ Assert.NotNull(t);
+ Assert.Equal([1, 2, 3, 4, 5], entity.Header);
}
[Fact]
@@ -691,11 +692,11 @@ public async Task TryConvertTo_Null()
MockEntity? entity = null;
// 设置数据适配器
- var adapter = new MockErrorEntityDataPackageAdapter
+ var adapter = new DataPackageAdapter
{
DataPackageHandler = new FixLengthDataPackageHandler(7),
};
- client.SetDataPackageAdapter(adapter, t =>
+ client.SetDataPackageAdapter(adapter, new MockEntitySocketDataConverter(), t =>
{
entity = t;
tcs.SetResult();
@@ -710,7 +711,7 @@ public async Task TryConvertTo_Null()
await client.SendAsync(data);
await tcs.Task;
- Assert.Null(entity);
+ Assert.NotNull(entity);
}
private static TcpListener StartTcpServer(int port, Func handler)
@@ -1080,9 +1081,9 @@ public void SetReceive(bool state)
}
}
- class MockEntityDataPackageAdapter : DataPackageAdapter
+ class MockEntitySocketDataConverter : SocketDataConverterBase
{
- public override bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out object? entity)
+ public override bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out MockEntity? entity)
{
entity = new MockEntity
{
@@ -1093,15 +1094,6 @@ public override bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)]
}
}
- class MockErrorEntityDataPackageAdapter : DataPackageAdapter
- {
- public override bool TryConvertTo(ReadOnlyMemory data, [NotNullWhen(true)] out object? entity)
- {
- entity = new Foo();
- return true;
- }
- }
-
class MockEntity
{
public byte[]? Header { get; set; }