From ba31886db7df58a6be03ca28a9347ea4b8a41fcf Mon Sep 17 00:00:00 2001 From: patheems Date: Sun, 13 Sep 2020 09:09:08 +0200 Subject: [PATCH] Solve the issue of being restricted to using Newtonsoft (#664) * Solve the issue of being restricted to using Newtonsoft for serialization/deserialization. * Removed whitespace * Failed build fixed by injecting ISerializer. * Removed unintended reference. Co-authored-by: Patrick Heemskerk --- .../CAP.DashboardOptionsExtensions.cs | 3 +- .../DashboardRoutes.cs | 14 ++--- .../IDataStorage.InMemory.cs | 12 ++-- .../IDataStorage.MongoDB.cs | 14 +++-- .../IDataStorage.MySql.cs | 11 ++-- .../IDataStorage.PostgreSql.cs | 11 ++-- .../IDataStorage.SqlServer.cs | 11 ++-- .../Internal/IConsumerRegister.Default.cs | 2 +- .../Internal/ISubscribeInvoker.Default.cs | 10 +-- src/DotNetCore.CAP/Messages/Message.cs | 10 ++- .../Serialization/ISerializer.JsonUtf8.cs | 29 ++++++++- .../Serialization/ISerializer.cs | 32 +++++++++- .../MySqlStorageConnectionTest.cs | 4 +- test/DotNetCore.CAP.MySql.Test/TestHost.cs | 4 +- test/DotNetCore.CAP.Test/MessageTest.cs | 62 +++++++++++++++++++ .../SubscribeInvokerTest.cs | 2 + 16 files changed, 188 insertions(+), 43 deletions(-) create mode 100644 test/DotNetCore.CAP.Test/MessageTest.cs diff --git a/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs b/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs index 5a27d66..00db11d 100644 --- a/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs +++ b/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs @@ -6,6 +6,7 @@ using DotNetCore.CAP; using DotNetCore.CAP.Dashboard; using DotNetCore.CAP.Dashboard.GatewayProxy; using DotNetCore.CAP.Dashboard.GatewayProxy.Requester; +using DotNetCore.CAP.Serialization; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; @@ -26,7 +27,7 @@ namespace DotNetCore.CAP _options?.Invoke(dashboardOptions); services.AddTransient(); services.AddSingleton(dashboardOptions); - services.AddSingleton(DashboardRoutes.Routes); + services.AddSingleton(x => DashboardRoutes.GetDashboardRoutes(x.GetRequiredService())); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs b/src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs index 35105cf..4672f58 100644 --- a/src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs +++ b/src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.DependencyInjection; namespace DotNetCore.CAP.Dashboard { - public static class DashboardRoutes + public class DashboardRoutes { private static readonly string[] Javascripts = { @@ -33,9 +33,9 @@ namespace DotNetCore.CAP.Dashboard "cap.css" }; - static DashboardRoutes() + public static RouteCollection GetDashboardRoutes(ISerializer serializer) { - Routes = new RouteCollection(); + RouteCollection Routes = new RouteCollection(); Routes.AddRazorPage("/", x => new HomePage()); Routes.Add("/stats", new JsonStats()); Routes.Add("/health", new OkStats()); @@ -104,7 +104,7 @@ namespace DotNetCore.CAP.Dashboard { var msg = client.Storage.GetMonitoringApi().GetPublishedMessageAsync(messageId) .GetAwaiter().GetResult(); - msg.Origin = StringSerializer.DeSerialize(msg.Content); + msg.Origin = serializer.Deserialize(msg.Content); client.RequestServices.GetService().EnqueueToPublish(msg); }); Routes.AddPublishBatchCommand( @@ -113,7 +113,7 @@ namespace DotNetCore.CAP.Dashboard { var msg = client.Storage.GetMonitoringApi().GetReceivedMessageAsync(messageId) .GetAwaiter().GetResult(); - msg.Origin = StringSerializer.DeSerialize(msg.Content); + msg.Origin = serializer.Deserialize(msg.Content); client.RequestServices.GetService().DispatchAsync(msg); }); @@ -135,9 +135,9 @@ namespace DotNetCore.CAP.Dashboard Routes.AddRazorPage("/nodes/node/(?.+)", x => new NodePage(x.UriMatch.Groups["Id"].Value)); #endregion Razor pages and commands - } - public static RouteCollection Routes { get; } + return Routes; + } internal static string GetContentFolderNamespace(string contentFolder) { diff --git a/src/DotNetCore.CAP.InMemoryStorage/IDataStorage.InMemory.cs b/src/DotNetCore.CAP.InMemoryStorage/IDataStorage.InMemory.cs index ee01cf3..5730fec 100644 --- a/src/DotNetCore.CAP.InMemoryStorage/IDataStorage.InMemory.cs +++ b/src/DotNetCore.CAP.InMemoryStorage/IDataStorage.InMemory.cs @@ -19,10 +19,12 @@ namespace DotNetCore.CAP.InMemoryStorage internal class InMemoryStorage : IDataStorage { private readonly IOptions _capOptions; + private readonly ISerializer _serializer; - public InMemoryStorage(IOptions capOptions) + public InMemoryStorage(IOptions capOptions, ISerializer serializer) { _capOptions = capOptions; + _serializer = serializer; } public static ConcurrentDictionary PublishedMessages { get; } = new ConcurrentDictionary(); @@ -49,7 +51,7 @@ namespace DotNetCore.CAP.InMemoryStorage { DbId = content.GetId(), Origin = content, - Content = StringSerializer.Serialize(content), + Content = _serializer.Serialize(content), Added = DateTime.Now, ExpiresAt = null, Retries = 0 @@ -104,7 +106,7 @@ namespace DotNetCore.CAP.InMemoryStorage Origin = mdMessage.Origin, Group = group, Name = name, - Content = StringSerializer.Serialize(mdMessage.Origin), + Content = _serializer.Serialize(mdMessage.Origin), Retries = mdMessage.Retries, Added = mdMessage.Added, ExpiresAt = mdMessage.ExpiresAt, @@ -152,7 +154,7 @@ namespace DotNetCore.CAP.InMemoryStorage foreach (var message in ret) { - message.Origin = StringSerializer.DeSerialize(message.Content); + message.Origin = _serializer.Deserialize(message.Content); } return Task.FromResult(ret); @@ -169,7 +171,7 @@ namespace DotNetCore.CAP.InMemoryStorage foreach (var message in ret) { - message.Origin = StringSerializer.DeSerialize(message.Content); + message.Origin = _serializer.Deserialize(message.Content); } return Task.FromResult(ret); diff --git a/src/DotNetCore.CAP.MongoDB/IDataStorage.MongoDB.cs b/src/DotNetCore.CAP.MongoDB/IDataStorage.MongoDB.cs index 9275b31..86f1e39 100644 --- a/src/DotNetCore.CAP.MongoDB/IDataStorage.MongoDB.cs +++ b/src/DotNetCore.CAP.MongoDB/IDataStorage.MongoDB.cs @@ -11,7 +11,6 @@ using DotNetCore.CAP.Messages; using DotNetCore.CAP.Monitoring; using DotNetCore.CAP.Persistence; using DotNetCore.CAP.Serialization; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Driver; @@ -23,16 +22,19 @@ namespace DotNetCore.CAP.MongoDB private readonly IMongoClient _client; private readonly IMongoDatabase _database; private readonly IOptions _options; + private readonly ISerializer _serializer; public MongoDBDataStorage( IOptions capOptions, IOptions options, - IMongoClient client) + IMongoClient client, + ISerializer serializer) { _capOptions = capOptions; _options = options; _client = client; _database = _client.GetDatabase(_options.Value.DatabaseName); + _serializer = serializer; } public async Task ChangePublishStateAsync(MediumMessage message, StatusName state) @@ -67,7 +69,7 @@ namespace DotNetCore.CAP.MongoDB { DbId = content.GetId(), Origin = content, - Content = StringSerializer.Serialize(content), + Content = _serializer.Serialize(content), Added = DateTime.Now, ExpiresAt = null, Retries = 0 @@ -130,7 +132,7 @@ namespace DotNetCore.CAP.MongoDB ExpiresAt = null, Retries = 0 }; - var content = StringSerializer.Serialize(mdMessage.Origin); + var content = _serializer.Serialize(mdMessage.Origin); var collection = _database.GetCollection(_options.Value.ReceivedCollection); @@ -184,7 +186,7 @@ namespace DotNetCore.CAP.MongoDB return queryResult.Select(x => new MediumMessage { DbId = x.Id.ToString(), - Origin = StringSerializer.DeSerialize(x.Content), + Origin = _serializer.Deserialize(x.Content), Retries = x.Retries, Added = x.Added }).ToList(); @@ -205,7 +207,7 @@ namespace DotNetCore.CAP.MongoDB return queryResult.Select(x => new MediumMessage { DbId = x.Id.ToString(), - Origin = StringSerializer.DeSerialize(x.Content), + Origin = _serializer.Deserialize(x.Content), Retries = x.Retries, Added = x.Added }).ToList(); diff --git a/src/DotNetCore.CAP.MySql/IDataStorage.MySql.cs b/src/DotNetCore.CAP.MySql/IDataStorage.MySql.cs index 9199afb..3f3892c 100644 --- a/src/DotNetCore.CAP.MySql/IDataStorage.MySql.cs +++ b/src/DotNetCore.CAP.MySql/IDataStorage.MySql.cs @@ -22,17 +22,20 @@ namespace DotNetCore.CAP.MySql private readonly IOptions _options; private readonly IOptions _capOptions; private readonly IStorageInitializer _initializer; + private readonly ISerializer _serializer; private readonly string _pubName; private readonly string _recName; public MySqlDataStorage( IOptions options, IOptions capOptions, - IStorageInitializer initializer) + IStorageInitializer initializer, + ISerializer serializer) { _options = options; _capOptions = capOptions; _initializer = initializer; + _serializer = serializer; _pubName = initializer.GetPublishedTableName(); _recName = initializer.GetReceivedTableName(); } @@ -52,7 +55,7 @@ namespace DotNetCore.CAP.MySql { DbId = content.GetId(), Origin = content, - Content = StringSerializer.Serialize(content), + Content = _serializer.Serialize(content), Added = DateTime.Now, ExpiresAt = null, Retries = 0 @@ -122,7 +125,7 @@ namespace DotNetCore.CAP.MySql new MySqlParameter("@Id", mdMessage.DbId), new MySqlParameter("@Name", name), new MySqlParameter("@Group", group), - new MySqlParameter("@Content", StringSerializer.Serialize(mdMessage.Origin)), + new MySqlParameter("@Content", _serializer.Serialize(mdMessage.Origin)), new MySqlParameter("@Retries", mdMessage.Retries), new MySqlParameter("@Added", mdMessage.Added), new MySqlParameter("@ExpiresAt", mdMessage.ExpiresAt.HasValue ? (object) mdMessage.ExpiresAt.Value : DBNull.Value), @@ -194,7 +197,7 @@ namespace DotNetCore.CAP.MySql messages.Add(new MediumMessage { DbId = reader.GetInt64(0).ToString(), - Origin = StringSerializer.DeSerialize(reader.GetString(1)), + Origin = _serializer.Deserialize(reader.GetString(1)), Retries = reader.GetInt32(2), Added = reader.GetDateTime(3) }); diff --git a/src/DotNetCore.CAP.PostgreSql/IDataStorage.PostgreSql.cs b/src/DotNetCore.CAP.PostgreSql/IDataStorage.PostgreSql.cs index aa55d34..7d7f602 100644 --- a/src/DotNetCore.CAP.PostgreSql/IDataStorage.PostgreSql.cs +++ b/src/DotNetCore.CAP.PostgreSql/IDataStorage.PostgreSql.cs @@ -22,17 +22,20 @@ namespace DotNetCore.CAP.PostgreSql private readonly IOptions _capOptions; private readonly IStorageInitializer _initializer; private readonly IOptions _options; + private readonly ISerializer _serializer; private readonly string _pubName; private readonly string _recName; public PostgreSqlDataStorage( IOptions options, IOptions capOptions, - IStorageInitializer initializer) + IStorageInitializer initializer, + ISerializer serializer) { _capOptions = capOptions; _initializer = initializer; _options = options; + _serializer = serializer; _pubName = initializer.GetPublishedTableName(); _recName = initializer.GetReceivedTableName(); } @@ -53,7 +56,7 @@ namespace DotNetCore.CAP.PostgreSql { DbId = content.GetId(), Origin = content, - Content = StringSerializer.Serialize(content), + Content = _serializer.Serialize(content), Added = DateTime.Now, ExpiresAt = null, Retries = 0 @@ -121,7 +124,7 @@ namespace DotNetCore.CAP.PostgreSql new NpgsqlParameter("@Id", long.Parse(mdMessage.DbId)), new NpgsqlParameter("@Name", name), new NpgsqlParameter("@Group", group), - new NpgsqlParameter("@Content", StringSerializer.Serialize(mdMessage.Origin)), + new NpgsqlParameter("@Content", _serializer.Serialize(mdMessage.Origin)), new NpgsqlParameter("@Retries", mdMessage.Retries), new NpgsqlParameter("@Added", mdMessage.Added), new NpgsqlParameter("@ExpiresAt", mdMessage.ExpiresAt.HasValue ? (object) mdMessage.ExpiresAt.Value : DBNull.Value), @@ -199,7 +202,7 @@ namespace DotNetCore.CAP.PostgreSql messages.Add(new MediumMessage { DbId = reader.GetInt64(0).ToString(), - Origin = StringSerializer.DeSerialize(reader.GetString(1)), + Origin = _serializer.Deserialize(reader.GetString(1)), Retries = reader.GetInt32(2), Added = reader.GetDateTime(3) }); diff --git a/src/DotNetCore.CAP.SqlServer/IDataStorage.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/IDataStorage.SqlServer.cs index dc83dec..0db52d1 100644 --- a/src/DotNetCore.CAP.SqlServer/IDataStorage.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/IDataStorage.SqlServer.cs @@ -22,17 +22,20 @@ namespace DotNetCore.CAP.SqlServer private readonly IOptions _capOptions; private readonly IOptions _options; private readonly IStorageInitializer _initializer; + private readonly ISerializer _serializer; private readonly string _pubName; private readonly string _recName; public SqlServerDataStorage( IOptions capOptions, IOptions options, - IStorageInitializer initializer) + IStorageInitializer initializer, + ISerializer serializer) { _options = options; _initializer = initializer; _capOptions = capOptions; + _serializer = serializer; _pubName = initializer.GetPublishedTableName(); _recName = initializer.GetReceivedTableName(); } @@ -52,7 +55,7 @@ namespace DotNetCore.CAP.SqlServer { DbId = content.GetId(), Origin = content, - Content = StringSerializer.Serialize(content), + Content = _serializer.Serialize(content), Added = DateTime.Now, ExpiresAt = null, Retries = 0 @@ -120,7 +123,7 @@ namespace DotNetCore.CAP.SqlServer new SqlParameter("@Id", mdMessage.DbId), new SqlParameter("@Name", name), new SqlParameter("@Group", group), - new SqlParameter("@Content", StringSerializer.Serialize(mdMessage.Origin)), + new SqlParameter("@Content", _serializer.Serialize(mdMessage.Origin)), new SqlParameter("@Retries", mdMessage.Retries), new SqlParameter("@Added", mdMessage.Added), new SqlParameter("@ExpiresAt", mdMessage.ExpiresAt.HasValue ? (object) mdMessage.ExpiresAt.Value : DBNull.Value), @@ -200,7 +203,7 @@ namespace DotNetCore.CAP.SqlServer messages.Add(new MediumMessage { DbId = reader.GetInt64(0).ToString(), - Origin = StringSerializer.DeSerialize(reader.GetString(1)), + Origin = _serializer.Deserialize(reader.GetString(1)), Retries = reader.GetInt32(2), Added = reader.GetDateTime(3) }); diff --git a/src/DotNetCore.CAP/Internal/IConsumerRegister.Default.cs b/src/DotNetCore.CAP/Internal/IConsumerRegister.Default.cs index c41c96d..9b1098b 100644 --- a/src/DotNetCore.CAP/Internal/IConsumerRegister.Default.cs +++ b/src/DotNetCore.CAP/Internal/IConsumerRegister.Default.cs @@ -195,7 +195,7 @@ namespace DotNetCore.CAP.Internal if (message.HasException()) { - var content = StringSerializer.Serialize(message); + var content = _serializer.Serialize(message); _storage.StoreReceivedExceptionMessage(name, group, content); diff --git a/src/DotNetCore.CAP/Internal/ISubscribeInvoker.Default.cs b/src/DotNetCore.CAP/Internal/ISubscribeInvoker.Default.cs index 2db57d4..dd6da06 100644 --- a/src/DotNetCore.CAP/Internal/ISubscribeInvoker.Default.cs +++ b/src/DotNetCore.CAP/Internal/ISubscribeInvoker.Default.cs @@ -8,10 +8,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Serialization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; namespace DotNetCore.CAP.Internal { @@ -19,11 +19,13 @@ namespace DotNetCore.CAP.Internal { private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; + private readonly ISerializer _serializer; private readonly ConcurrentDictionary _executors; - public SubscribeInvoker(ILoggerFactory loggerFactory, IServiceProvider serviceProvider) + public SubscribeInvoker(ILoggerFactory loggerFactory, IServiceProvider serviceProvider, ISerializer serializer) { _serviceProvider = serviceProvider; + _serializer = serializer; _logger = loggerFactory.CreateLogger(); _executors = new ConcurrentDictionary(); } @@ -57,9 +59,9 @@ namespace DotNetCore.CAP.Internal { if (message.Value != null) { - if (message.Value is JToken jToken) //reading from storage + if (_serializer.IsJsonType(message.Value)) // use ISerializer when reading from storage, skip other objects if not Json { - executeParameters[i] = jToken.ToObject(parameterDescriptors[i].ParameterType); + executeParameters[i] = _serializer.Deserialize(message.Value, parameterDescriptors[i].ParameterType); } else { diff --git a/src/DotNetCore.CAP/Messages/Message.cs b/src/DotNetCore.CAP/Messages/Message.cs index 6ab4935..eb52659 100644 --- a/src/DotNetCore.CAP/Messages/Message.cs +++ b/src/DotNetCore.CAP/Messages/Message.cs @@ -9,16 +9,22 @@ namespace DotNetCore.CAP.Messages { public class Message { + /// + /// System.Text.Json requires that class explicitly has a parameterless constructor + /// and public properties have a setter. + /// + public Message() {} + public Message(IDictionary headers, [CanBeNull] object value) { Headers = headers ?? throw new ArgumentNullException(nameof(headers)); Value = value; } - public IDictionary Headers { get; } + public IDictionary Headers { get; set; } [CanBeNull] - public object Value { get; } + public object Value { get; set; } } public static class MessageExtensions diff --git a/src/DotNetCore.CAP/Serialization/ISerializer.JsonUtf8.cs b/src/DotNetCore.CAP/Serialization/ISerializer.JsonUtf8.cs index a2e534a..70ab10e 100644 --- a/src/DotNetCore.CAP/Serialization/ISerializer.JsonUtf8.cs +++ b/src/DotNetCore.CAP/Serialization/ISerializer.JsonUtf8.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using DotNetCore.CAP.Messages; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace DotNetCore.CAP.Serialization { @@ -37,5 +38,29 @@ namespace DotNetCore.CAP.Serialization var json = Encoding.UTF8.GetString(transportMessage.Body); return Task.FromResult(new Message(transportMessage.Headers, JsonConvert.DeserializeObject(json, valueType))); } - } -} + + public string Serialize(Message message) + { + return JsonConvert.SerializeObject(message); + } + + public Message Deserialize(string json) + { + return JsonConvert.DeserializeObject(json); + } + + public object Deserialize(object value, Type valueType) + { + if (value is JToken jToken) + { + return jToken.ToObject(valueType); + } + throw new NotSupportedException("Type is not of type JToken"); + } + + public bool IsJsonType(object jsonObject) + { + return jsonObject is JToken; + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Serialization/ISerializer.cs b/src/DotNetCore.CAP/Serialization/ISerializer.cs index 0c831f7..ee6135a 100644 --- a/src/DotNetCore.CAP/Serialization/ISerializer.cs +++ b/src/DotNetCore.CAP/Serialization/ISerializer.cs @@ -16,8 +16,38 @@ namespace DotNetCore.CAP.Serialization Task SerializeAsync(Message message); /// - /// Deserializes the given back into a + /// Deserialize the given back into a /// Task DeserializeAsync(TransportMessage transportMessage, [CanBeNull] Type valueType); + + /// + /// Serializes the given into a string + /// + string Serialize(Message message); + + /// + /// Deserialize the given string into a + /// + Message Deserialize(string json); + + /// + /// Deserialize the given object with the given Type into an object + /// + object Deserialize(object value, Type valueType); + + /// + /// Check if the given object is of Json type, e.g. JToken or JsonElement + /// depending on the type of serializer implemented + /// + /// + /// + /// // Example implementation for System.Text.Json + /// public bool IsJsonType(object jsonObject) + /// { + /// return jsonObject is JsonElement; + /// } + /// + /// + bool IsJsonType(object jsonObject); } } \ No newline at end of file diff --git a/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs b/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs index 12fb9e2..3a2e0b4 100644 --- a/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs +++ b/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using DotNetCore.CAP.Internal; using DotNetCore.CAP.Messages; using DotNetCore.CAP.Persistence; +using DotNetCore.CAP.Serialization; using Microsoft.Extensions.Options; using Xunit; @@ -15,10 +16,11 @@ namespace DotNetCore.CAP.MySql.Test public MySqlStorageConnectionTest() { + var serializer = GetService(); var options = GetService>(); var capOptions = GetService>(); var initializer = GetService(); - _storage = new MySqlDataStorage(options, capOptions, initializer); + _storage = new MySqlDataStorage(options, capOptions, initializer, serializer); } [Fact] diff --git a/test/DotNetCore.CAP.MySql.Test/TestHost.cs b/test/DotNetCore.CAP.MySql.Test/TestHost.cs index acb9fc0..35480bc 100644 --- a/test/DotNetCore.CAP.MySql.Test/TestHost.cs +++ b/test/DotNetCore.CAP.MySql.Test/TestHost.cs @@ -1,5 +1,6 @@ using System; using DotNetCore.CAP.Persistence; +using DotNetCore.CAP.Serialization; using Microsoft.Extensions.DependencyInjection; namespace DotNetCore.CAP.MySql.Test @@ -34,8 +35,9 @@ namespace DotNetCore.CAP.MySql.Test { x.ConnectionString = ConnectionString; }); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); _services = services; } diff --git a/test/DotNetCore.CAP.Test/MessageTest.cs b/test/DotNetCore.CAP.Test/MessageTest.cs new file mode 100644 index 0000000..133c24a --- /dev/null +++ b/test/DotNetCore.CAP.Test/MessageTest.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Serialization; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace DotNetCore.CAP.Test +{ + public class MessageTest + { + private readonly IServiceProvider _provider; + + public MessageTest() + { + var services = new ServiceCollection(); + ServiceCollectionExtensions.ServiceCollection = services; + + services.AddSingleton(); + _provider = services.BuildServiceProvider(); + } + + [Fact] + public void Serialize_then_Deserialize_Message_With_Utf8JsonSerializer() + { + // Given + var givenMessage = new Message( + headers: new Dictionary() { + { "cap-msg-name", "authentication.users.update"}, + { "cap-msg-type", "User" }, + { "cap-corr-seq", "0"}, + { "cap-msg-group","service.v1"} + }, + value: new MessageValue("test@test.com", "User")); + + // When + var serializer = _provider.GetRequiredService(); + var json = serializer.Serialize(givenMessage); + var deserializedMessage = serializer.Deserialize(json); + + // Then + Assert.True(serializer.IsJsonType(deserializedMessage.Value)); + + var result = serializer.Deserialize(deserializedMessage.Value, typeof(MessageValue)) as MessageValue; + Assert.NotNull(result); + Assert.Equal(result.Email, ((MessageValue)givenMessage.Value).Email); + Assert.Equal(result.Name, ((MessageValue)givenMessage.Value).Name); + } + } + + public class MessageValue + { + public MessageValue(string email, string name) + { + Email = email; + Name = name; + } + + public string Email { get; } + public string Name { get; } + } +} \ No newline at end of file diff --git a/test/DotNetCore.CAP.Test/SubscribeInvokerTest.cs b/test/DotNetCore.CAP.Test/SubscribeInvokerTest.cs index 9815bf0..5db7959 100644 --- a/test/DotNetCore.CAP.Test/SubscribeInvokerTest.cs +++ b/test/DotNetCore.CAP.Test/SubscribeInvokerTest.cs @@ -4,6 +4,7 @@ using System.Reflection; using System.Threading.Tasks; using DotNetCore.CAP.Internal; using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Serialization; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -17,6 +18,7 @@ namespace DotNetCore.CAP.Test { var serviceCollection = new ServiceCollection(); serviceCollection.AddLogging(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); _serviceProvider = serviceCollection.BuildServiceProvider(); }