Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.6.2 #81

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Represents the **NuGet** versions.

## v3.6.2
- *Enhancement:* Added `Converter.Create<TSource, TDestionation>` to enable a simple one-off `IConverter<TSource, TDestionation>` implementation to be created.
- *Fixed:* The `IReferenceData.SetInvalid` method corrected to throw `NotImplementedException` where not explicitly implemented.
- *Fixed:* The `ReferenceDataBase` updated to handle the `IsValid` and `SetInvalid` functionality correctly.

## v3.6.1
- *Enhancement:* Added `IBidirectionalMapper<TFrom, TTo>` to enable a single mapping capability that can support mapping both ways.
- *Enhancement:* Added `IBidirectionalMapper<TFrom, TTo>` registration support to `Mapper.Register` and by extension `IServiceCollection.AddMappings`.
Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.6.1</Version>
<Version>3.6.2</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
22 changes: 22 additions & 0 deletions src/CoreEx/Mapping/Converters/Converter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx

using System;

namespace CoreEx.Mapping.Converters
{
/// <summary>
/// Enables the <see cref="Create"/> of a <see cref="Converter{TSource, TDestination}"/> instance.
/// </summary>
public static class Converter
{
/// <summary>
/// Provides a generic means to create a one-off <see cref="Converter{TSource, TDestination}"/> instance.
/// </summary>
/// <typeparam name="TSource">The source <see cref="Type"/>.</typeparam>
/// <typeparam name="TDestination">The destination <see cref="Type"/>.</typeparam>
/// <param name="toDestination">The <typeparamref name="TSource"/> to <typeparamref name="TDestination"/> conversion logic.</param>
/// <param name="toSource">The <typeparamref name="TDestination"/> to <typeparamref name="TSource"/> conversion logic.</param>
/// <returns>The <see cref="Converter{TSource, TDestination}"/>.</returns>
public static Converter<TSource, TDestination> Create<TSource, TDestination>(Func<TSource, TDestination> toDestination, Func<TDestination, TSource> toSource) => new(toDestination, toSource);
}
}
29 changes: 29 additions & 0 deletions src/CoreEx/Mapping/Converters/ConverterT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx

using System;

namespace CoreEx.Mapping.Converters
{
/// <summary>
/// Provides a generic means to create a one-off <see cref="IConverter{TSource, TDestination}"/> instance.
/// </summary>
/// <typeparam name="TSource">The source <see cref="Type"/>.</typeparam>
/// <typeparam name="TDestination">The destination <see cref="Type"/>.</typeparam>
/// <param name="toDestination">The <typeparamref name="TSource"/> to <typeparamref name="TDestination"/> conversion logic.</param>
/// <param name="toSource">The <typeparamref name="TDestination"/> to <typeparamref name="TSource"/> conversion logic.</param>
public readonly struct Converter<TSource, TDestination>(Func<TSource, TDestination> toDestination, Func<TDestination, TSource> toSource) : IConverter<TSource, TDestination>
{
private readonly ValueConverter<TSource, TDestination> _convertToDestination = new(toDestination);
private readonly ValueConverter<TDestination, TSource> _convertToSource = new(toSource);

/// <summary>
/// Gets the source to destination <see cref="IValueConverter{TSource, TDestination}"/>.
/// </summary>
public readonly IValueConverter<TSource, TDestination> ToDestination => _convertToDestination;

/// <summary>
/// Gets the destination to source <see cref="IValueConverter{TDestination, TSource}"/>.
/// </summary>
public readonly IValueConverter<TDestination, TSource> ToSource => _convertToSource;
}
}
5 changes: 3 additions & 2 deletions src/CoreEx/RefData/Extended/ReferenceDataBaseEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace CoreEx.RefData.Extended
/// <summary>
/// Represents the extended <see cref="IReferenceData"/> <see cref="EntityBase"/> base implementation.
/// </summary>
/// <remarks>The <see cref="Id"/> can only be of type <see cref="int"/>, <see cref="long"/>, <see cref="string"/> and <see cref="Guid"/>.</remarks>
/// <remarks>The <see cref="Id"/> can only be of type <see cref="int"/>, <see cref="long"/>, <see cref="string"/> and <see cref="Guid"/>.
/// <para>This implementation is fully-featured and is generally intended for usage within backend services.</para></remarks>
[DebuggerDisplay("Id = {Id}, Code = {Code}, Text = {Text}, IsActive = {IsActive}")]
public class ReferenceDataBaseEx<TId, TSelf> : EntityBase, IReferenceData<TId> where TId : IComparable<TId>, IEquatable<TId> where TSelf : ReferenceDataBaseEx<TId, TSelf>, new()
{
Expand All @@ -40,7 +41,7 @@ public ReferenceDataBaseEx()
}

/// <inheritdoc/>
Type IIdentifier.IdType { get => typeof(TId); }
Type IIdentifier.IdType => typeof(TId);

/// <inheritdoc/>
object? IIdentifier.Id { get => Id; set => Id = (TId)value!; }
Expand Down
4 changes: 2 additions & 2 deletions src/CoreEx/RefData/IReferenceData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public interface IReferenceData : IIdentifier, IETag
/// Overrides the standard <see cref="IsValid"/> check and flags the <see cref="ReferenceDataBaseEx{TId, TSelf}"/> as <b>Invalid</b>.
/// </summary>
/// <remarks>Will result in <see cref="IsActive"/> set to <c>false</c>. Once set to invalid it can not be changed; i.e. there is not an means to set back to valid.</remarks>
void SetInvalid() { }
void SetInvalid() => throw new NotImplementedException("Either explicity override this functionality or leverage the ReferenceDataBaseEx class that enables.");

/// <summary>
/// Gets the underlying mapping dictionary.
Expand All @@ -83,7 +83,7 @@ void SetInvalid() { }
/// <param name="name">The mapping name.</param>
/// <param name="value">The mapping value.</param>
/// <remarks>A <paramref name="value"/> with the default value will not be set; assumed in this case that no mapping exists.</remarks>
public void SetMapping<T>(string name, T? value) where T : IComparable<T?>, IEquatable<T?> => throw new NotImplementedException();
public void SetMapping<T>(string name, T? value) where T : IComparable<T?>, IEquatable<T?> => throw new NotImplementedException("Either explicity override this functionality or leverage the ReferenceDataBaseEx class that enables.");

/// <summary>
/// Gets a mapping value for the <see cref="ReferenceDataBaseEx{TId, TSelf}"/> for the specified <paramref name="name"/>.
Expand Down
19 changes: 10 additions & 9 deletions src/CoreEx/RefData/ReferenceDataBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
namespace CoreEx.RefData
{
/// <summary>
/// Represents the <see cref="IReferenceData"/> implementation.
/// Represents the basic <see cref="IReferenceData"/> implementation.
/// </summary>
/// <remarks>For a fully-featured implementation see <see cref="Extended.ReferenceDataBaseEx{TId, TSelf}"/>.</remarks>
[DebuggerDisplay("Id = {Id}, Code = {Code}, Text = {Text}, IsActive = {IsActive}")]
public abstract class ReferenceDataBase : IReferenceData
{
private Type _idType = null!;
private bool _isValid = true;

/// <inheritdoc/>
Type IIdentifier.IdType => _idType;
Type IIdentifier.IdType => throw new NotImplementedException();

/// <inheritdoc/>
public object? Id { get; set; }
Expand Down Expand Up @@ -45,12 +46,12 @@ public abstract class ReferenceDataBase : IReferenceData
public string? ETag { get; set; }

/// <inheritdoc/>
public override string ToString() => Text ?? Code ?? Id?.ToString() ?? base.ToString()!;
bool IReferenceData.IsValid => _isValid;

/// <inheritdoc/>
void IReferenceData.SetInvalid() => _isValid = false;

/// <summary>
/// Sets the underlying <see cref="IIdentifier.IdType"/>.
/// </summary>
/// <param name="type">The <see cref="IIdentifier.IdType"/>.</param>
protected void SetIdType(Type type) => _idType = type;
/// <inheritdoc/>
public override string ToString() => Text ?? Code ?? Id?.ToString() ?? base.ToString()!;
}
}
5 changes: 4 additions & 1 deletion src/CoreEx/RefData/ReferenceDataBaseT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace CoreEx.RefData
/// <summary>
/// Represents the <see cref="IReferenceData{TId}"/> implementation.
/// </summary>
/// <remarks>For a fully-featured implementation see <see cref="Extended.ReferenceDataBaseEx{TId, TSelf}"/>.</remarks>
[DebuggerDisplay("Id = {Id}, Code = {Code}, Text = {Text}, IsActive = {IsActive}")]
public class ReferenceDataBase<TId> : ReferenceDataBase, IReferenceData<TId> where TId : IComparable<TId>, IEquatable<TId>
{
Expand All @@ -18,7 +19,6 @@ public class ReferenceDataBase<TId> : ReferenceDataBase, IReferenceData<TId> whe
/// <remarks>The <see cref="Id"/> can only be of type <see cref="int"/>, <see cref="long"/>, <see cref="string"/> and <see cref="Guid"/>.</remarks>
public ReferenceDataBase()
{
SetIdType(typeof(TId));
base.Id = default(TId);
if (Id != null && Id is not int && Id is not long && Id is not string && Id is not Guid)
throw new InvalidOperationException($"A Reference Data {nameof(Id)} can only be of type {nameof(Int32)}, {nameof(Int64)}, {nameof(String)} or {nameof(Guid)}.");
Expand All @@ -27,6 +27,9 @@ public ReferenceDataBase()
/// <inheritdoc/>
object? IIdentifier.Id { get => base.Id; set => base.Id = (TId)value!; }

/// <inheritdoc/>
Type IIdentifier.IdType => typeof(TId);

/// <inheritdoc/>
public new TId? Id { get => (TId?)base.Id; set => base.Id = value; }
}
Expand Down
16 changes: 16 additions & 0 deletions tests/CoreEx.Test/Framework/Mapping/Converters/ConverterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using NUnit.Framework;

namespace CoreEx.Test.Framework.Mapping.Converters
{
[TestFixture]
public class ConverterTest
{
[Test]
public void Convert()
{
var converter = CoreEx.Mapping.Converters.Converter.Create<string, int>(s => int.Parse(s), i => i.ToString());
Assert.AreEqual(123, converter.ToDestination.Convert("123"));
Assert.AreEqual("123", converter.ToSource.Convert(123));
}
}
}
8 changes: 8 additions & 0 deletions tests/CoreEx.Test/Framework/RefData/ReferenceDataTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ public void RefDataSimple()
Assert.AreEqual("XX", r.Text);

Assert.AreEqual(typeof(int), ((IIdentifier)r).IdType);

var ir = (IReferenceData)r;
Assert.IsTrue(ir.IsValid);
ir.SetInvalid();
Assert.IsFalse(ir.IsValid);
Assert.AreSame(ir.IdType, typeof(int));

Assert.AreEqual("{\"id\":1,\"code\":\"X\",\"text\":\"XX\"}", new CoreEx.Text.Json.ReferenceDataContentJsonSerializer().Serialize(r));
}

[Test]
Expand Down
Loading