* 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 <pheemskerk@inforit.nl>master
@@ -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<IStartupFilter, CapStartupFilter>(); | |||
services.AddSingleton(dashboardOptions); | |||
services.AddSingleton(DashboardRoutes.Routes); | |||
services.AddSingleton(x => DashboardRoutes.GetDashboardRoutes(x.GetRequiredService<ISerializer>())); | |||
services.AddSingleton<IHttpRequester, HttpClientHttpRequester>(); | |||
services.AddSingleton<IHttpClientCache, MemoryHttpClientCache>(); | |||
services.AddSingleton<IRequestMapper, RequestMapper>(); | |||
@@ -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<IDispatcher>().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<ISubscribeDispatcher>().DispatchAsync(msg); | |||
}); | |||
@@ -135,9 +135,9 @@ namespace DotNetCore.CAP.Dashboard | |||
Routes.AddRazorPage("/nodes/node/(?<Id>.+)", 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) | |||
{ | |||
@@ -19,10 +19,12 @@ namespace DotNetCore.CAP.InMemoryStorage | |||
internal class InMemoryStorage : IDataStorage | |||
{ | |||
private readonly IOptions<CapOptions> _capOptions; | |||
private readonly ISerializer _serializer; | |||
public InMemoryStorage(IOptions<CapOptions> capOptions) | |||
public InMemoryStorage(IOptions<CapOptions> capOptions, ISerializer serializer) | |||
{ | |||
_capOptions = capOptions; | |||
_serializer = serializer; | |||
} | |||
public static ConcurrentDictionary<string, MemoryMessage> PublishedMessages { get; } = new ConcurrentDictionary<string, MemoryMessage>(); | |||
@@ -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); | |||
@@ -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<MongoDBOptions> _options; | |||
private readonly ISerializer _serializer; | |||
public MongoDBDataStorage( | |||
IOptions<CapOptions> capOptions, | |||
IOptions<MongoDBOptions> 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<ReceivedMessage>(_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(); | |||
@@ -22,17 +22,20 @@ namespace DotNetCore.CAP.MySql | |||
private readonly IOptions<MySqlOptions> _options; | |||
private readonly IOptions<CapOptions> _capOptions; | |||
private readonly IStorageInitializer _initializer; | |||
private readonly ISerializer _serializer; | |||
private readonly string _pubName; | |||
private readonly string _recName; | |||
public MySqlDataStorage( | |||
IOptions<MySqlOptions> options, | |||
IOptions<CapOptions> 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) | |||
}); | |||
@@ -22,17 +22,20 @@ namespace DotNetCore.CAP.PostgreSql | |||
private readonly IOptions<CapOptions> _capOptions; | |||
private readonly IStorageInitializer _initializer; | |||
private readonly IOptions<PostgreSqlOptions> _options; | |||
private readonly ISerializer _serializer; | |||
private readonly string _pubName; | |||
private readonly string _recName; | |||
public PostgreSqlDataStorage( | |||
IOptions<PostgreSqlOptions> options, | |||
IOptions<CapOptions> 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) | |||
}); | |||
@@ -22,17 +22,20 @@ namespace DotNetCore.CAP.SqlServer | |||
private readonly IOptions<CapOptions> _capOptions; | |||
private readonly IOptions<SqlServerOptions> _options; | |||
private readonly IStorageInitializer _initializer; | |||
private readonly ISerializer _serializer; | |||
private readonly string _pubName; | |||
private readonly string _recName; | |||
public SqlServerDataStorage( | |||
IOptions<CapOptions> capOptions, | |||
IOptions<SqlServerOptions> 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) | |||
}); | |||
@@ -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); | |||
@@ -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<int, ObjectMethodExecutor> _executors; | |||
public SubscribeInvoker(ILoggerFactory loggerFactory, IServiceProvider serviceProvider) | |||
public SubscribeInvoker(ILoggerFactory loggerFactory, IServiceProvider serviceProvider, ISerializer serializer) | |||
{ | |||
_serviceProvider = serviceProvider; | |||
_serializer = serializer; | |||
_logger = loggerFactory.CreateLogger<SubscribeInvoker>(); | |||
_executors = new ConcurrentDictionary<int, ObjectMethodExecutor>(); | |||
} | |||
@@ -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 | |||
{ | |||
@@ -9,16 +9,22 @@ namespace DotNetCore.CAP.Messages | |||
{ | |||
public class Message | |||
{ | |||
/// <summary> | |||
/// System.Text.Json requires that class explicitly has a parameterless constructor | |||
/// and public properties have a setter. | |||
/// </summary> | |||
public Message() {} | |||
public Message(IDictionary<string, string> headers, [CanBeNull] object value) | |||
{ | |||
Headers = headers ?? throw new ArgumentNullException(nameof(headers)); | |||
Value = value; | |||
} | |||
public IDictionary<string, string> Headers { get; } | |||
public IDictionary<string, string> Headers { get; set; } | |||
[CanBeNull] | |||
public object Value { get; } | |||
public object Value { get; set; } | |||
} | |||
public static class MessageExtensions | |||
@@ -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<Message>(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; | |||
} | |||
} | |||
} |
@@ -16,8 +16,38 @@ namespace DotNetCore.CAP.Serialization | |||
Task<TransportMessage> SerializeAsync(Message message); | |||
/// <summary> | |||
/// Deserializes the given <see cref="TransportMessage"/> back into a <see cref="Message"/> | |||
/// Deserialize the given <see cref="TransportMessage"/> back into a <see cref="Message"/> | |||
/// </summary> | |||
Task<Message> DeserializeAsync(TransportMessage transportMessage, [CanBeNull] Type valueType); | |||
/// <summary> | |||
/// Serializes the given <see cref="Message"/> into a string | |||
/// </summary> | |||
string Serialize(Message message); | |||
/// <summary> | |||
/// Deserialize the given string into a <see cref="Message"/> | |||
/// </summary> | |||
Message Deserialize(string json); | |||
/// <summary> | |||
/// Deserialize the given object with the given Type into an object | |||
/// </summary> | |||
object Deserialize(object value, Type valueType); | |||
/// <summary> | |||
/// Check if the given object is of Json type, e.g. JToken or JsonElement | |||
/// depending on the type of serializer implemented | |||
/// </summary> | |||
/// <example> | |||
/// <code> | |||
/// // Example implementation for System.Text.Json | |||
/// public bool IsJsonType(object jsonObject) | |||
/// { | |||
/// return jsonObject is JsonElement; | |||
/// } | |||
/// </code> | |||
/// </example> | |||
bool IsJsonType(object jsonObject); | |||
} | |||
} |
@@ -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<ISerializer>(); | |||
var options = GetService<IOptions<MySqlOptions>>(); | |||
var capOptions = GetService<IOptions<CapOptions>>(); | |||
var initializer = GetService<IStorageInitializer>(); | |||
_storage = new MySqlDataStorage(options, capOptions, initializer); | |||
_storage = new MySqlDataStorage(options, capOptions, initializer, serializer); | |||
} | |||
[Fact] | |||
@@ -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<MySqlDataStorage>(); | |||
services.AddSingleton<MySqlDataStorage>(); | |||
services.AddSingleton<IStorageInitializer,MySqlStorageInitializer>(); | |||
services.AddSingleton<ISerializer, JsonUtf8Serializer>(); | |||
_services = services; | |||
} | |||
@@ -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<ISerializer, JsonUtf8Serializer>(); | |||
_provider = services.BuildServiceProvider(); | |||
} | |||
[Fact] | |||
public void Serialize_then_Deserialize_Message_With_Utf8JsonSerializer() | |||
{ | |||
// Given | |||
var givenMessage = new Message( | |||
headers: new Dictionary<string, string>() { | |||
{ "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<ISerializer>(); | |||
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; } | |||
} | |||
} |
@@ -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<ISerializer, JsonUtf8Serializer>(); | |||
serviceCollection.AddSingleton<ISubscribeInvoker, SubscribeInvoker>(); | |||
_serviceProvider = serviceCollection.BuildServiceProvider(); | |||
} | |||