mirror of
https://github.com/Stone-Red-Code/CuteUtils.git
synced 2026-09-09 07:46:13 +02:00
Add DynDto and minor improvements
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\CuteUtils\CuteUtils.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using CuteUtils.Reflection;
|
||||||
|
|
||||||
|
using System.Dynamic;
|
||||||
|
|
||||||
|
namespace CuteUtils.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class UnitTest1
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void TestMethod1()
|
||||||
|
{
|
||||||
|
TestModel testModel = new()
|
||||||
|
{
|
||||||
|
Id = 13,
|
||||||
|
Name = "test",
|
||||||
|
Value = (15, "test"),
|
||||||
|
};
|
||||||
|
|
||||||
|
ExpandoObject dto = testModel.ToDto();
|
||||||
|
|
||||||
|
Assert.IsNotNull(dto);
|
||||||
|
|
||||||
|
Assert.IsFalse(dto.Any(p => p.Key == "Id"));
|
||||||
|
Assert.IsTrue(dto.Any(p => p.Key == "Name"));
|
||||||
|
Assert.IsTrue(dto.Any(p => p.Key == "Value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestMethod2()
|
||||||
|
{
|
||||||
|
TestModel testModel = new()
|
||||||
|
{
|
||||||
|
Id = 13,
|
||||||
|
Name = "test",
|
||||||
|
Value = (15, "test"),
|
||||||
|
};
|
||||||
|
|
||||||
|
TestDto dto = testModel.ToDto<TestDto>();
|
||||||
|
|
||||||
|
Assert.IsNotNull(dto);
|
||||||
|
|
||||||
|
Assert.IsTrue(dto.Id != 0);
|
||||||
|
Assert.IsTrue(dto.Name is not null);
|
||||||
|
Assert.IsTrue(dto.Value is not null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestModel
|
||||||
|
{
|
||||||
|
public required int Id { get; set; }
|
||||||
|
|
||||||
|
[DynDtoName(nameof(Name))]
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
//[DynDtoName(nameof(Value))]
|
||||||
|
public required object Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; } = 0;
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public object Value { get; set; } = (15, "test");
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-1
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.9.34622.214
|
VisualStudioVersion = 17.9.34622.214
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CuteUtils", "CuteUtils\CuteUtils.csproj", "{D640F3B6-2B09-496D-88D6-3CF57559845D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CuteUtils", "CuteUtils\CuteUtils.csproj", "{D640F3B6-2B09-496D-88D6-3CF57559845D}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CuteUtils.Tests", "CuteUtils.Tests\CuteUtils.Tests.csproj", "{1468822C-92E4-4C44-93F6-DE71930F7C96}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -15,6 +17,10 @@ Global
|
|||||||
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D640F3B6-2B09-496D-88D6-3CF57559845D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1468822C-92E4-4C44-93F6-DE71930F7C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1468822C-92E4-4C44-93F6-DE71930F7C96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1468822C-92E4-4C44-93F6-DE71930F7C96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1468822C-92E4-4C44-93F6-DE71930F7C96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -8,26 +8,26 @@ public static class BoolExt
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets value to true if input is true. If input is false the value will not change.
|
/// Sets value to true if input is true. If input is false the value will not change.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bol"></param>
|
/// <param name="value"></param>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
public static void OneWayTrue(this ref bool bol, bool input)
|
public static void OneWayTrue(this ref bool value, bool input)
|
||||||
{
|
{
|
||||||
if (!bol && input)
|
if (!value && input)
|
||||||
{
|
{
|
||||||
bol = true;
|
value = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets value to false if input is false. If input is true the value will not change.
|
/// Sets value to false if input is false. If input is true the value will not change.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bol"></param>
|
/// <param name="value"></param>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
public static void OneWayFalse(this ref bool bol, bool input)
|
public static void OneWayFalse(this ref bool value, bool input)
|
||||||
{
|
{
|
||||||
if (bol && !input)
|
if (value && !input)
|
||||||
{
|
{
|
||||||
bol = false;
|
value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Reactive.Linq" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using Stone_Red_C_Sharp_Utilities.Logging;
|
namespace CuteUtils.Logging;
|
||||||
|
|
||||||
using Stone_Red_Utilities.Logging;
|
|
||||||
|
|
||||||
namespace CuteUtils.Logging;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logging configuration.
|
/// Logging configuration.
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Stone_Red_C_Sharp_Utilities.Logging;
|
using System.Text;
|
||||||
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace CuteUtils.Logging;
|
namespace CuteUtils.Logging;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Stone_Red_C_Sharp_Utilities;
|
using System.Diagnostics;
|
||||||
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace CuteUtils.Logging;
|
namespace CuteUtils.Logging;
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using System.Dynamic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace CuteUtils.Reflection;
|
||||||
|
public static class DynDto
|
||||||
|
{
|
||||||
|
public static ExpandoObject ToDto(this object data)
|
||||||
|
{
|
||||||
|
ExpandoObject dto = new ExpandoObject();
|
||||||
|
|
||||||
|
PropertyInfo[] properties = data.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo property in properties)
|
||||||
|
{
|
||||||
|
DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute<DynDtoNameAttribute>();
|
||||||
|
|
||||||
|
if (dynDtoNameAttribute is not null)
|
||||||
|
{
|
||||||
|
_ = dto.TryAdd(dynDtoNameAttribute.Name, property.GetValue(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T ToDto<T>(this object data, T dto)
|
||||||
|
{
|
||||||
|
PropertyInfo[] dataProperties = data.GetType().GetProperties();
|
||||||
|
PropertyInfo[] dtoProperties = data.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo dataProperty in dataProperties)
|
||||||
|
{
|
||||||
|
DynDtoNameAttribute? dynDtoNameAttribute = dataProperty.GetCustomAttribute<DynDtoNameAttribute>();
|
||||||
|
PropertyInfo? dtoPropertyInfo = Array.Find(dtoProperties, p => p.Name == dynDtoNameAttribute?.Name);
|
||||||
|
|
||||||
|
if (dynDtoNameAttribute is not null && dtoPropertyInfo is not null)
|
||||||
|
{
|
||||||
|
object? value = dataProperty.GetValue(data);
|
||||||
|
dtoPropertyInfo.SetValue(dto, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T ToDto<T>(this object data) where T : new()
|
||||||
|
{
|
||||||
|
return ToDto(data, new T());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T FromDto<T>(this object dto, T data)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(data);
|
||||||
|
|
||||||
|
PropertyInfo[] dataProperties = data.GetType().GetProperties();
|
||||||
|
PropertyInfo[] dtoProperties = dto.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo property in dataProperties)
|
||||||
|
{
|
||||||
|
DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute<DynDtoNameAttribute>();
|
||||||
|
if (dynDtoNameAttribute is not null)
|
||||||
|
{
|
||||||
|
PropertyInfo? propertyInfo = Array.Find(dtoProperties, x => x.Name == dynDtoNameAttribute.Name);
|
||||||
|
|
||||||
|
if (propertyInfo is not null)
|
||||||
|
{
|
||||||
|
property.SetValue(data, propertyInfo.GetValue(dto));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T FromDto<T>(this ExpandoObject dto, T data)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(dto);
|
||||||
|
ArgumentNullException.ThrowIfNull(data);
|
||||||
|
|
||||||
|
IDictionary<string, object> dtoProperties = dto!;
|
||||||
|
|
||||||
|
PropertyInfo[] dataProperties = data.GetType().GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo property in dataProperties)
|
||||||
|
{
|
||||||
|
DynDtoNameAttribute? dynDtoNameAttribute = property.GetCustomAttribute<DynDtoNameAttribute>();
|
||||||
|
if (dynDtoNameAttribute is not null && dtoProperties.TryGetValue(dynDtoNameAttribute.Name, out object? value))
|
||||||
|
{
|
||||||
|
property.SetValue(data, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T FromDto<T>(this object dto) where T : new()
|
||||||
|
{
|
||||||
|
return FromDto(dto, new T());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T FromDto<T>(this ExpandoObject dto) where T : new()
|
||||||
|
{
|
||||||
|
return FromDto(dto, new T());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace CuteUtils.Reflection;
|
||||||
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||||
|
public class DynDtoNameAttribute(string name) : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = name;
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace CuteUtils;
|
namespace CuteUtils.Reflection;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reflection class
|
/// Reflection class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Reflection
|
public static class ReflectionExtentions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies all properties of an object to a new one.
|
/// Copies all properties of an object to a new one.
|
||||||
Reference in New Issue
Block a user