diff --git a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
index 316aab3..9565292 100644
--- a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
@@ -1,4 +1,4 @@
-using DD.Persistence.Models;
+using DD.Persistence.Models;
using DD.Persistence.Models.Common;
namespace DD.Persistence.Client.Clients.Interfaces;
@@ -37,18 +37,6 @@ public interface ITimestampedValuesClient : IDisposable
int take,
CancellationToken token);
- ///
- /// Получить данные с фильтрацией для нескольких систем. Значение фильтра null - отключен
- ///
- ///
- ///
- ///
- /// Фильтр свойств набора
- ///
- ///
- ///
- Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token);
-
///
/// Получить данные, начиная с заданной отметки времени
///
@@ -97,13 +85,6 @@ public interface ITimestampedValuesClient : IDisposable
///
Task GetDatesRange(Guid discriminatorId, CancellationToken token);
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- Task> GetLast(Guid idDiscriminator, int take, CancellationToken token);
+
+
}
\ No newline at end of file
diff --git a/DD.Persistence.Client/Clients/Mapping/Abstractions/IMapperStorage.cs b/DD.Persistence.Client/Clients/Mapping/Abstractions/IMapperStorage.cs
new file mode 100644
index 0000000..dd08e76
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/Abstractions/IMapperStorage.cs
@@ -0,0 +1,6 @@
+namespace DD.Persistence.Client.Clients.Mapping.Abstractions;
+internal interface IMapperStorage
+{
+ TimestampedSetMapper GetMapper(Guid idDiscriminator);
+ TimestampedSetMapper? GetMapper(Guid idDiscriminator);
+}
diff --git a/DD.Persistence.Client/Clients/Mapping/Abstractions/ISetpointMappingClient.cs b/DD.Persistence.Client/Clients/Mapping/Abstractions/ISetpointMappingClient.cs
new file mode 100644
index 0000000..02f64b0
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/Abstractions/ISetpointMappingClient.cs
@@ -0,0 +1,6 @@
+using DD.Persistence.Client.Clients.Interfaces;
+
+namespace DD.Persistence.Client.Clients.Mapping.Abstractions;
+public interface ISetpointMappingClient : ISetpointClient
+{
+}
diff --git a/DD.Persistence.Client/Clients/Mapping/Abstractions/ITimestampedMappingClient.cs b/DD.Persistence.Client/Clients/Mapping/Abstractions/ITimestampedMappingClient.cs
new file mode 100644
index 0000000..6be0e58
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/Abstractions/ITimestampedMappingClient.cs
@@ -0,0 +1,45 @@
+using DD.Persistence.Client.Clients.Interfaces;
+
+namespace DD.Persistence.Client.Clients.Mapping.Abstractions;
+
+///
+/// Маппинг - обертка для клиента по работе с данными
+///
+public interface ITimestampedMappingClient : ITimestampedValuesClient
+{
+ ///
+ /// Получить данные с преобразованием к заданному типу
+ ///
+ ///
+ ///
+ /// Фильтр свойств набора
+ ///
+ ///
+ ///
+ ///
+ Task> GetMapped(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token);
+
+ ///
+ /// Получить набор данных, преобразованных к соответствующим типам из заданного конфига
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task>> GetMultiMapped(IEnumerable discriminatorIds, DateTimeOffset? timestampBegin, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token);
+
+
+ ///
+ /// Получить данные с конца с преобразованием к заданному типу
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task> GetLastMapped(Guid idDiscriminator, int take, CancellationToken token);
+}
diff --git a/DD.Persistence.Client/Clients/Mapping/Clients/SetpointMappingClient.cs b/DD.Persistence.Client/Clients/Mapping/Clients/SetpointMappingClient.cs
new file mode 100644
index 0000000..1942ad4
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/Clients/SetpointMappingClient.cs
@@ -0,0 +1,103 @@
+using DD.Persistence.Client.Clients.Interfaces;
+using DD.Persistence.Client.Clients.Mapping.Abstractions;
+using DD.Persistence.Models;
+using DD.Persistence.Models.Common;
+using DD.Persistence.Models.Configurations;
+using System.Text.Json;
+
+namespace DD.Persistence.Client.Clients.Mapping.Clients;
+
+///
+public class SetpointMappingClient : ISetpointMappingClient
+{
+ private readonly ISetpointClient setpointClient;
+ private readonly MappingConfig mappingConfigs;
+
+ ///
+ public SetpointMappingClient(ISetpointClient setpointClient, MappingConfig mappingConfigs)
+ {
+ this.setpointClient = setpointClient;
+ this.mappingConfigs = mappingConfigs;
+ }
+
+ ///
+ public async Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token)
+ => (await setpointClient.GetCurrent(setpointKeys, token))
+ .Select(x => new SetpointValueDto
+ {
+ Key = x.Key,
+ Value = DeserializeValue(x.Key, (JsonElement)x.Value)
+ });
+
+ ///
+ public async Task> GetCurrentDictionary(IEnumerable setpointConfigs, CancellationToken token)
+ {
+ var result = (await setpointClient.GetCurrent(setpointConfigs, token))
+ .ToDictionary(x => x.Key, x => DeserializeValue(x.Key, (JsonElement)x.Value));
+
+ return result;
+ }
+
+ ///
+ public async Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
+ {
+ var result = await setpointClient.GetHistory(setpointKeys, historyMoment, token);
+
+ foreach (var dto in result)
+ dto.Value = DeserializeValue(dto.Key, (JsonElement)dto.Value);
+
+ return result;
+ }
+
+ ///
+ public async Task>> GetLog(IEnumerable setpointKeys, CancellationToken token)
+ {
+ var result = await setpointClient.GetLog(setpointKeys, token);
+
+ foreach (var item in result)
+ DeserializeList(result[item.Key]);
+
+ return result;
+ }
+
+ ///
+ public async Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token)
+ {
+ var result = await setpointClient.GetPart(dateBegin, take, token);
+
+ DeserializeList(result);
+
+ return result;
+ }
+
+ ///
+ public async Task Add(Guid setpointKey, object newValue, CancellationToken token)
+ => await setpointClient.Add(setpointKey, newValue, token);
+
+ ///
+ public async Task GetDatesRangeAsync(CancellationToken token)
+ => await setpointClient.GetDatesRangeAsync(token);
+
+ ///
+ public void Dispose()
+ {
+ setpointClient.Dispose();
+
+ }
+
+ private object DeserializeValue(Guid key, JsonElement value)
+ {
+ if (mappingConfigs.TryGetValue(key, out var type))
+ return value.Deserialize(type)!;
+
+ return value;
+ }
+ private void DeserializeList(IEnumerable? result)
+ {
+ if (result is null)
+ return;
+
+ foreach (var log in result)
+ log.Value = DeserializeValue(log.Key, (JsonElement)log.Value);
+ }
+}
diff --git a/DD.Persistence.Client/Clients/Mapping/Clients/TimestampedMappingClient.cs b/DD.Persistence.Client/Clients/Mapping/Clients/TimestampedMappingClient.cs
new file mode 100644
index 0000000..09aa283
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/Clients/TimestampedMappingClient.cs
@@ -0,0 +1,107 @@
+using DD.Persistence.Client.Clients.Interfaces;
+using DD.Persistence.Client.Clients.Mapping.Abstractions;
+using DD.Persistence.Models;
+using DD.Persistence.Models.Common;
+using Microsoft.Extensions.Logging;
+
+namespace DD.Persistence.Client.Clients.Mapping.Clients;
+
+///
+internal class TimestampedMappingClient : ITimestampedMappingClient
+{
+ private readonly ITimestampedValuesClient client;
+ private readonly IMapperStorage mapperStorage;
+
+ public TimestampedMappingClient(ITimestampedValuesClient client, IMapperStorage mapperStorage)
+ {
+ this.client = client;
+ this.mapperStorage = mapperStorage;
+ }
+
+ ///
+ public async Task> GetMapped(Guid discriminatorId, DateTimeOffset? geTimestamp,
+ string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ {
+ var data = await Get([discriminatorId], geTimestamp, filterTree, columnNames, skip, take, token);
+ var mapper = mapperStorage.GetMapper(discriminatorId);
+
+ var mappedDtos = data.Select(mapper.DeserializeTimeStampedData).OfType();
+
+ return mappedDtos;
+ }
+
+ ///
+ public async Task> GetLastMapped(Guid idDiscriminator, int take, CancellationToken token)
+ {
+ var data = await GetLast(idDiscriminator, take, token);
+ var mapper = mapperStorage.GetMapper(idDiscriminator);
+
+ var mappedDtos = data.Select(mapper.DeserializeTimeStampedData).OfType();
+
+ return mappedDtos;
+ }
+
+ ///
+ public async Task>> GetMultiMapped(IEnumerable discriminatorIds, DateTimeOffset? geTimestamp,
+ string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ {
+ var data = await client.Get(discriminatorIds, geTimestamp, filterTree, columnNames, skip, take, token);
+
+ var result = discriminatorIds
+ .ToDictionary(discriminatorId => discriminatorId, discriminatorId =>
+ {
+ var mapper = mapperStorage.GetMapper(discriminatorId);
+
+ ArgumentNullException.ThrowIfNull(mapper);
+
+ var mappedDtos = data
+ .Where(e => e.DiscriminatorId == discriminatorId)
+ .Select(mapper.DeserializeTimeStampedData);
+
+ return mappedDtos;
+ });
+
+ return result;
+ }
+
+ ///
+ public async Task AddRange(Guid discriminatorId, IEnumerable dtos, CancellationToken token)
+ => await client.AddRange(discriminatorId, dtos, token);
+
+ ///
+ public async Task Count(Guid discriminatorId, CancellationToken token)
+ => await client.Count(discriminatorId, token);
+
+ ///
+ public async Task> Get(IEnumerable discriminatorIds, DateTimeOffset? timestampBegin,
+ string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ => await client.Get(discriminatorIds, timestampBegin, filterTree, columnNames, skip, take, token);
+
+ ///
+ public async Task GetDatesRange(Guid discriminatorId, CancellationToken token)
+ => await client.GetDatesRange(discriminatorId, token);
+
+ ///
+ public async Task> GetFirst(Guid discriminatorId, int take, CancellationToken token)
+ => await client.GetFirst(discriminatorId, take, token);
+
+ ///
+ public async Task> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
+ => await client.GetGtDate(discriminatorId, timestampBegin, token);
+
+ ///
+ public async Task> GetLast(Guid discriminatorId, int take, CancellationToken token)
+ => await client.GetLast(discriminatorId, take, token);
+
+ ///
+ public async Task> GetResampledData(Guid discriminatorId, DateTimeOffset timestampBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
+ => await client.GetResampledData(discriminatorId, timestampBegin, intervalSec, approxPointsCount, token);
+
+ ///
+ public void Dispose()
+ {
+ client.Dispose();
+ }
+
+
+}
diff --git a/DD.Persistence.Client/Clients/Mapping/MapperStorage.cs b/DD.Persistence.Client/Clients/Mapping/MapperStorage.cs
new file mode 100644
index 0000000..74d33d7
--- /dev/null
+++ b/DD.Persistence.Client/Clients/Mapping/MapperStorage.cs
@@ -0,0 +1,33 @@
+using DD.Persistence.Client.Clients.Mapping.Abstractions;
+using DD.Persistence.Models.Configurations;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Concurrent;
+
+namespace DD.Persistence.Client.Clients.Mapping;
+internal class MapperStorage : IMapperStorage
+{
+ private readonly ConcurrentDictionary mapperCache = new();
+ private readonly MappingConfig mappingConfigs;
+ private readonly ILogger logger;
+
+ public MapperStorage(MappingConfig mappingConfigs, ILogger logger)
+ {
+ this.mappingConfigs = mappingConfigs;
+ this.logger = logger;
+ }
+
+
+ public TimestampedSetMapper? GetMapper(Guid idDiscriminator)
+ {
+ if (mappingConfigs.TryGetValue(idDiscriminator, out var type))
+ return mapperCache.GetOrAdd(idDiscriminator, name => new TimestampedSetMapper(idDiscriminator, type, logger));
+
+ return null;
+ }
+
+ public TimestampedSetMapper GetMapper(Guid idDiscriminator)
+ {
+ return mapperCache.GetOrAdd(idDiscriminator, name => new TimestampedSetMapper(idDiscriminator, typeof(T), logger));
+ }
+}
diff --git a/DD.Persistence.Client/TimestampedSetMapper.cs b/DD.Persistence.Client/Clients/Mapping/TimestampedSetMapper.cs
similarity index 59%
rename from DD.Persistence.Client/TimestampedSetMapper.cs
rename to DD.Persistence.Client/Clients/Mapping/TimestampedSetMapper.cs
index cf7463a..38c1bea 100644
--- a/DD.Persistence.Client/TimestampedSetMapper.cs
+++ b/DD.Persistence.Client/Clients/Mapping/TimestampedSetMapper.cs
@@ -1,65 +1,62 @@
using DD.Persistence.Models;
+using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Json;
-namespace DD.Persistence.Client;
+namespace DD.Persistence.Client.Clients.Mapping;
-internal abstract class TimestampedSetMapperBase
+internal class TimestampedSetMapper
{
- public abstract object Map(TimestampedValuesDto data);
+ private readonly Type entityType;
+ private readonly ILogger logger;
-}
-internal class TimestampedSetMapper : TimestampedSetMapperBase
-{
- private readonly Type entityType = typeof(T);
public Guid IdDiscriminator { get; }
private readonly ConcurrentDictionary PropertyCache = new();
- public TimestampedSetMapper(Guid idDiscriminator)
+ public TimestampedSetMapper(Guid idDiscriminator, Type entityType, ILogger logger)
{
IdDiscriminator = idDiscriminator;
+ this.entityType = entityType;
+ this.logger = logger;
}
- public override object Map(TimestampedValuesDto data)
+ public object DeserializeTimeStampedData(TimestampedValuesDto data)
{
- return DeserializeTimeStampedData(data)!;
- }
-
- public T DeserializeTimeStampedData(TimestampedValuesDto data)
- {
-
if (entityType.IsValueType)
return MapStruct(data);
- else
- return MapClass(data);
+
+ return MapClass(data);
}
- private T MapClass(TimestampedValuesDto data)
+ private object MapClass(TimestampedValuesDto data)
{
- var entity = (T)RuntimeHelpers.GetUninitializedObject(typeof(T));
+ var entity = RuntimeHelpers.GetUninitializedObject(entityType);
foreach (var (propertyName, value) in data.Values)
{
if (value is JsonElement jsonElement)
SetPropertyValueFromJson(ref entity, propertyName, jsonElement);
}
- SetPropertyValue(ref entity, "Timestamp", data.Timestamp);
+ SetPropertyValue(ref entity, nameof(TimestampedValuesDto.Timestamp), data.Timestamp);
+ SetPropertyValue(ref entity, nameof(TimestampedValuesDto.DiscriminatorId), data.DiscriminatorId);
+
return entity;
}
- private T MapStruct(TimestampedValuesDto data)
+ private object MapStruct(TimestampedValuesDto data)
{
- var entity = Activator.CreateInstance();
+ var entity = Activator.CreateInstance(entityType);
object boxedEntity = entity!;
foreach (var (propertyName, value) in data.Values)
{
if (value is JsonElement jsonElement)
SetPropertyValueForStructFromJson(ref boxedEntity, propertyName, jsonElement);
}
- SetPropertyValueForStruct(ref boxedEntity, "Timestamp", data.Timestamp);
+ SetPropertyValueForStruct(ref boxedEntity, nameof(TimestampedValuesDto.Timestamp), data.Timestamp);
+ SetPropertyValueForStruct(ref boxedEntity, nameof(TimestampedValuesDto.DiscriminatorId), data.DiscriminatorId);
- return (T)boxedEntity;
+ return boxedEntity;
}
private void SetPropertyValueForStructFromJson(ref object entity, string propertyName, JsonElement element)
@@ -73,8 +70,9 @@ internal class TimestampedSetMapper : TimestampedSetMapperBase
var value = element.Deserialize(property.PropertyType);
property.SetValue(entity, value);
}
- catch (Exception ex)
+ catch (Exception ex)
{
+ logger.LogError(ex.Message);
}
}
private void SetPropertyValueForStruct(ref object entity, string propertyName, object value)
@@ -88,13 +86,14 @@ internal class TimestampedSetMapper : TimestampedSetMapperBase
var convertedValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(entity, convertedValue);
}
- catch (Exception ex)
+ catch (Exception ex)
{
+ logger.LogError(ex.Message);
}
}
- private void SetPropertyValueFromJson(ref T entity, string propertyName, JsonElement jsonElement)
+ private void SetPropertyValueFromJson(ref object entity, string propertyName, JsonElement jsonElement)
{
var property = GetPropertyInfo(propertyName);
@@ -106,13 +105,13 @@ internal class TimestampedSetMapper : TimestampedSetMapperBase
var value = jsonElement.Deserialize(property.PropertyType);
property.SetValue(entity, value);
}
- catch (Exception ex)
+ catch (Exception ex)
{
-
+ logger.LogError(ex.Message);
}
}
- private void SetPropertyValue(ref T entity, string propertyName, object value)
+ private void SetPropertyValue(ref object entity, string propertyName, object value)
{
var property = GetPropertyInfo(propertyName);
if (property is null)
@@ -123,8 +122,9 @@ internal class TimestampedSetMapper : TimestampedSetMapperBase
var convertedValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(entity, convertedValue);
}
- catch (Exception ex)
+ catch (Exception ex)
{
+ logger.LogError(ex.Message);
}
}
diff --git a/DD.Persistence.Client/Clients/SetpointClient.cs b/DD.Persistence.Client/Clients/SetpointClient.cs
index dfb5026..a2c401e 100644
--- a/DD.Persistence.Client/Clients/SetpointClient.cs
+++ b/DD.Persistence.Client/Clients/SetpointClient.cs
@@ -3,9 +3,6 @@ using DD.Persistence.Client.Clients.Base;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Models;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Globalization;
using DD.Persistence.Models.Common;
namespace DD.Persistence.Client.Clients;
@@ -13,15 +10,12 @@ namespace DD.Persistence.Client.Clients;
public class SetpointClient : BaseClient, ISetpointClient
{
private readonly IRefitSetpointClient refitSetpointClient;
- private readonly ISetpointConfigStorage setpointConfigStorage;
public SetpointClient(
IRefitClientFactory refitSetpointClientFactory,
- ISetpointConfigStorage setpointConfigStorage,
ILogger logger) : base(logger)
{
this.refitSetpointClient = refitSetpointClientFactory.Create();
- this.setpointConfigStorage = setpointConfigStorage;
}
public async Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token)
@@ -31,7 +25,7 @@ public class SetpointClient : BaseClient, ISetpointClient
return result!.Select(x => new SetpointValueDto {
Key = x.Key,
- Value = DeserializeValue(x.Key, x.Value)
+ Value = x.Value
});
}
@@ -43,16 +37,13 @@ public class SetpointClient : BaseClient, ISetpointClient
async () => await refitSetpointClient.GetCurrent(setpointConfigs, token), token);
- return result!.ToDictionary(x => x.Key,x => DeserializeValue(x.Key,x.Value));
+ return result!.ToDictionary(x => x.Key,x => (object)x.Value);
}
public async Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
{
var result = await ExecuteGetResponse(
async () => await refitSetpointClient.GetHistory(setpointKeys, historyMoment, token), token);
-
- foreach(var dto in result)
- dto.Value = DeserializeValue(dto.Key, (JsonElement)dto.Value);
return result!;
@@ -63,9 +54,6 @@ public class SetpointClient : BaseClient, ISetpointClient
var result = await ExecuteGetResponse(
async () => await refitSetpointClient.GetLog(setpointKeys, token), token);
- foreach(var item in result)
- DeserializeList(result[item.Key]);
-
return result!;
}
@@ -82,8 +70,6 @@ public class SetpointClient : BaseClient, ISetpointClient
var result = await ExecuteGetResponse(
async () => await refitSetpointClient.GetPart(dateBegin, take, token), token);
- DeserializeList(result);
-
return result!;
}
@@ -101,21 +87,4 @@ public class SetpointClient : BaseClient, ISetpointClient
GC.SuppressFinalize(this);
}
-
-
- private object DeserializeValue(Guid key, JsonElement value)
- {
- if (setpointConfigStorage.TryGetType(key, out var type))
- return value.Deserialize(type)!;
-
- return value;
- }
- private void DeserializeList(IEnumerable? result)
- {
- foreach (var log in result)
- log.Value = DeserializeValue(log.Key, (JsonElement)log.Value);
-
- }
-
-
}
diff --git a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
index e4ad2a0..dc0699f 100644
--- a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
@@ -1,4 +1,4 @@
-using DD.Persistence.Client.Clients.Base;
+using DD.Persistence.Client.Clients.Base;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Models;
@@ -19,8 +19,7 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
this.refitTimestampedSetClient = refitTimestampedSetClientFactory.Create();
}
- ///
- private readonly ConcurrentDictionary mapperCache = new();
+
///
public async Task AddRange(Guid discriminatorId, IEnumerable sets, CancellationToken token)
@@ -39,15 +38,6 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
return result!;
}
- ///
- public async Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, string? filterTree, IEnumerable? columnNames, int skip, int take, CancellationToken token)
- {
- var data = await Get([discriminatorId], geTimestamp, filterTree, columnNames, skip, take, token);
- var mapper = GetMapper(discriminatorId);
-
- return data.Select(mapper.DeserializeTimeStampedData);
- }
-
///
public async Task> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
{
@@ -102,20 +92,7 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
return result;
}
- ///
- public async Task> GetLast(Guid idDiscriminator, int take, CancellationToken token)
- {
- var data = await GetLast(idDiscriminator, take, token);
- var mapper = GetMapper(idDiscriminator);
-
- return data.Select(mapper.DeserializeTimeStampedData);
- }
-
- ///
- private TimestampedSetMapper GetMapper(Guid idDiscriminator)
- {
- return (TimestampedSetMapper)mapperCache.GetOrAdd(idDiscriminator, name => new TimestampedSetMapper(idDiscriminator));
- }
+
///
public void Dispose()
diff --git a/DD.Persistence.Client/DependencyInjection.cs b/DD.Persistence.Client/DependencyInjection.cs
index 89f65cf..f759bd8 100644
--- a/DD.Persistence.Client/DependencyInjection.cs
+++ b/DD.Persistence.Client/DependencyInjection.cs
@@ -1,6 +1,10 @@
using DD.Persistence.Client.Clients;
using DD.Persistence.Client.Clients.Interfaces;
+using DD.Persistence.Client.Clients.Mapping;
+using DD.Persistence.Client.Clients.Mapping.Abstractions;
+using DD.Persistence.Client.Clients.Mapping.Clients;
using DD.Persistence.Models;
+using DD.Persistence.Models.Configurations;
using Microsoft.Extensions.DependencyInjection;
namespace DD.Persistence.Client;
@@ -15,7 +19,7 @@ public static class DependencyInjection
///
///
///
- public static IServiceCollection AddPersistenceClients(this IServiceCollection services, Dictionary? setpointTypeConfigs = null)
+ public static IServiceCollection AddPersistenceClients(this IServiceCollection services)
{
services.AddTransient(typeof(IRefitClientFactory<>), typeof(RefitClientFactory<>));
services.AddTransient();
@@ -25,10 +29,17 @@ public static class DependencyInjection
services.AddTransient();
services.AddTransient();
- services.AddSingleton(provider =>
- {
- return new SetpointConfigStorage(setpointTypeConfigs);
- });
+ return services;
+ }
+
+
+ public static IServiceCollection AddPersistenceMapping(this IServiceCollection services, MappingConfig mappingConfigs)
+ {
+ services.AddSingleton(mappingConfigs);
+ services.AddSingleton();
+
+ services.AddTransient();
+ services.AddTransient();
return services;
}
}
diff --git a/DD.Persistence.Client/ISetpointConfigStorage.cs b/DD.Persistence.Client/ISetpointConfigStorage.cs
deleted file mode 100644
index 2c73783..0000000
--- a/DD.Persistence.Client/ISetpointConfigStorage.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace DD.Persistence.Client;
-public interface ISetpointConfigStorage
-{
- bool TryGetType(Guid id, out Type type);
-}
diff --git a/DD.Persistence.Client/SetpointConfigStorage.cs b/DD.Persistence.Client/SetpointConfigStorage.cs
deleted file mode 100644
index 5cfbabf..0000000
--- a/DD.Persistence.Client/SetpointConfigStorage.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace DD.Persistence.Client;
-internal class SetpointConfigStorage : ISetpointConfigStorage
-{
- private readonly Dictionary setpointTypeConfigs;
-
- public SetpointConfigStorage(Dictionary? setpointTypeConfigs)
- {
- this.setpointTypeConfigs = setpointTypeConfigs?? new Dictionary();
- }
-
- public bool TryGetType(Guid id, out Type type)
- {
- return setpointTypeConfigs.TryGetValue(id, out type);
- }
-
- public void AddOrReplace(Guid id, Type type)
- {
- setpointTypeConfigs[id] = type;
- }
-}
diff --git a/DD.Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs
index 64506dc..a2080b0 100644
--- a/DD.Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs
+++ b/DD.Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs
@@ -1,10 +1,10 @@
using DD.Persistence.Client;
-using DD.Persistence.Client.Clients;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
+using DD.Persistence.Client.Clients.Mapping.Clients;
using DD.Persistence.Database.Entity;
+using DD.Persistence.Models.Configurations;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
using System.Text.Json;
using Xunit;
@@ -13,17 +13,14 @@ namespace DD.Persistence.IntegrationTests.Controllers
public class SetpointControllerTest : BaseIntegrationTest
{
private readonly ISetpointClient setpointClient;
- private readonly SetpointConfigStorage configStorage;
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
{
var refitClientFactory = scope.ServiceProvider
.GetRequiredService>();
- var logger = scope.ServiceProvider.GetRequiredService>();
setpointClient = scope.ServiceProvider
.GetRequiredService();
- configStorage = (SetpointConfigStorage)scope.ServiceProvider.GetRequiredService();
}
@@ -32,12 +29,16 @@ namespace DD.Persistence.IntegrationTests.Controllers
{
var id = Guid.Parse("e0fcad22-1761-476e-a729-a3c59d51ba41");
- configStorage.AddOrReplace(id, typeof(float));
+ var config = new MappingConfig();
+ config[id] = typeof(float);
+
+ var setpointMapper = new SetpointMappingClient(setpointClient, config);
+
await setpointClient.Add(id, 48.3f, CancellationToken.None);
//act
- var response = await setpointClient.GetCurrent([id], CancellationToken.None);
+ var response = await setpointMapper.GetCurrent([id], CancellationToken.None);
//assert
Assert.NotNull(response);
diff --git a/DD.Persistence.Models/Configurations/MappingConfig.cs b/DD.Persistence.Models/Configurations/MappingConfig.cs
new file mode 100644
index 0000000..bc9f85e
--- /dev/null
+++ b/DD.Persistence.Models/Configurations/MappingConfig.cs
@@ -0,0 +1,4 @@
+namespace DD.Persistence.Models.Configurations;
+public class MappingConfig : Dictionary
+{
+}
diff --git a/DD.Persistence.Models/TimestampedValuesDto.cs b/DD.Persistence.Models/TimestampedValuesDto.cs
index 13b592e..dbb04f9 100644
--- a/DD.Persistence.Models/TimestampedValuesDto.cs
+++ b/DD.Persistence.Models/TimestampedValuesDto.cs
@@ -7,6 +7,11 @@ namespace DD.Persistence.Models;
///
public class TimestampedValuesDto : ITimestampAbstractDto
{
+ ///
+ /// Дискриминатор
+ ///
+ public Guid DiscriminatorId { get; set; }
+
///
/// Временная отметка
///
diff --git a/DD.Persistence.Test/DD.Persistence.Test.csproj b/DD.Persistence.Test/DD.Persistence.Test.csproj
index 07e0780..7006f98 100644
--- a/DD.Persistence.Test/DD.Persistence.Test.csproj
+++ b/DD.Persistence.Test/DD.Persistence.Test.csproj
@@ -1,4 +1,4 @@
-
+
net9.0
@@ -17,6 +17,7 @@
+
diff --git a/DD.Persistence.Test/MappingClientsTest.cs b/DD.Persistence.Test/MappingClientsTest.cs
new file mode 100644
index 0000000..b5d2e70
--- /dev/null
+++ b/DD.Persistence.Test/MappingClientsTest.cs
@@ -0,0 +1,99 @@
+using DD.Persistence.Client.Clients.Interfaces;
+using DD.Persistence.Client.Clients.Mapping;
+using DD.Persistence.Client.Clients.Mapping.Clients;
+using DD.Persistence.Models;
+using DD.Persistence.Models.Configurations;
+using Microsoft.Extensions.Logging;
+using NSubstitute;
+using System.Text.Json;
+
+namespace DD.Persistence.Test;
+
+public record FirstTestDto(Guid DiscriminatorId, DateTimeOffset Timestamp, int Id, string? Value);
+
+public record SecondTestDto(Guid DiscriminatorId, DateTimeOffset Timestamp, int Id, double Capacity);
+
+public class MappingClientsTest
+{
+ private readonly ITimestampedValuesClient timestampedValuesClient = Substitute.For();
+ private readonly ILogger logger = Substitute.For>();
+ private readonly TimestampedMappingClient timestampedMappingClient;
+
+ private readonly MappingConfig mappingConfigs;
+
+
+ public MappingClientsTest()
+ {
+ mappingConfigs = GetConfig();
+ var storage = new MapperStorage(mappingConfigs, logger);
+
+ timestampedMappingClient = new TimestampedMappingClient(timestampedValuesClient, storage);
+ }
+
+
+
+ [Fact]
+ public async Task GetMultiMapped()
+ {
+ // Arrange
+ var discriminatorIds = mappingConfigs.Keys;
+ var firstDiscriminatorId = discriminatorIds.First();
+ var secondDiscriminatorId = discriminatorIds.Last();
+ var getResult = new[]
+ {
+ new TimestampedValuesDto()
+ {
+ DiscriminatorId = firstDiscriminatorId,
+ Timestamp = DateTime.UtcNow,
+ Values = new Dictionary
+ {
+ { nameof(FirstTestDto.Id), JsonDocument.Parse(JsonSerializer.Serialize(1)).RootElement },
+ { nameof(FirstTestDto.Value), JsonDocument.Parse(JsonSerializer.Serialize("string1")).RootElement}
+ }
+ },
+ new TimestampedValuesDto()
+ {
+ DiscriminatorId = secondDiscriminatorId,
+ Timestamp = DateTime.UtcNow,
+ Values = new Dictionary
+ {
+ { nameof(SecondTestDto.Id), JsonDocument.Parse(JsonSerializer.Serialize(1)).RootElement },
+ { nameof(SecondTestDto.Capacity), JsonDocument.Parse(JsonSerializer.Serialize(0.1)).RootElement}
+ }
+ }
+ };
+ timestampedValuesClient
+ .Get(discriminatorIds, null, null, null, 0, 1, CancellationToken.None)
+ .ReturnsForAnyArgs(getResult);
+
+ // Act
+ var result = await timestampedMappingClient.GetMultiMapped(discriminatorIds, null, null, null, 0, 1, CancellationToken.None);
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.NotEmpty(result);
+ Assert.Equal(getResult.Count(), result.Count());
+
+ var firstActualDto = (FirstTestDto) result[firstDiscriminatorId].First();
+ Assert.NotNull(firstActualDto);
+
+ var actualId = firstActualDto.Id.ToString();
+ var expectedId = getResult[0].Values[nameof(FirstTestDto.Id)].ToString();
+ Assert.Equal(expectedId, actualId);
+
+ var secondActualDto = (SecondTestDto) result[secondDiscriminatorId].First();
+ Assert.NotNull(secondActualDto);
+
+ actualId = secondActualDto.Id.ToString();
+ expectedId = getResult[1].Values[nameof(SecondTestDto.Id)].ToString();
+ Assert.Equal(expectedId, actualId);
+ }
+ private MappingConfig GetConfig()
+ {
+ var config = new MappingConfig();
+ config[Guid.NewGuid()] = typeof(FirstTestDto);
+ config[Guid.NewGuid()] = typeof(SecondTestDto);
+
+ return config;
+ }
+}
diff --git a/DD.Persistence/Services/TimestampedValuesService.cs b/DD.Persistence/Services/TimestampedValuesService.cs
index f18bcd9..d94b9f4 100644
--- a/DD.Persistence/Services/TimestampedValuesService.cs
+++ b/DD.Persistence/Services/TimestampedValuesService.cs
@@ -122,6 +122,7 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var dto = new TimestampedValuesDto()
{
+ DiscriminatorId = keyValuePair.Key,
Timestamp = Timestamp.ToUniversalTime(),
Values = dataScheme
.ToDictionary(k => k.PropertyName, v => Values[v.Index])
diff --git a/Directory.Build.props b/Directory.Build.props
index cffb4fe..74c5ac9 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -8,6 +8,9 @@
<_Parameter1>DD.Persistence.IntegrationTests
+
+ <_Parameter1>DD.Persistence.Test
+
<_Parameter1>DynamicProxyGenAssembly2