Skip to content

Commit

Permalink
Implemented TypeAdapter methods to validate destination props with so…
Browse files Browse the repository at this point in the history
…urce
  • Loading branch information
haritha99ch committed Oct 8, 2023
1 parent 04ac871 commit 7445200
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/Mapster/TypeAdapter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Mapster.Models;

namespace Mapster
{
Expand Down Expand Up @@ -170,6 +173,60 @@ public static TDestination Adapt<TSource, TDestination>(this TSource source, TDe
return del.DynamicInvoke(source, destination);
}
}

/// <summary>
/// Validate properties and Adapt the source object to the destination type.
/// </summary>
/// <typeparam name="TSource">Source type.</typeparam>
/// <typeparam name="TDestination">Destination type.</typeparam>
/// <param name="source">Source object to adapt.</param>
/// <returns>Adapted destination type.</returns>
public static TDestination ValidateAndAdapt<TSource, TDestination>(this TSource source)
{
var entityType = typeof(TSource);
var selectorType = typeof(TDestination);

var entityProperties = new HashSet<string>(entityType.GetProperties().Select(p => p.Name));
var selectorProperties = new HashSet<string>(selectorType.GetProperties().Select(p=> p.Name));

foreach (var selectorProperty in selectorProperties)
{
if (entityProperties.Contains(selectorProperty)) continue;
throw new Exception($"Property {selectorProperty} does not exist in {entityType.Name} and is not configured in Mapster");
}
return source.Adapt<TDestination>();
}

/// <summary>
/// Validate properties and Adapt the source object to the destination type.
/// </summary>
/// <typeparam name="TSource">Source type.</typeparam>
/// <typeparam name="TDestination">Destination type.</typeparam>
/// <param name="source">Source object to adapt.</param>
/// <param name="config">Configuration</param>
/// <returns>Adapted destination type.</returns>
public static TDestination ValidateAndAdapt<TSource, TDestination>(this TSource source, TypeAdapterConfig config)
{
var entityType = typeof(TSource);
var selectorType = typeof(TDestination);

var entityProperties = new HashSet<string>(entityType.GetProperties().Select(p => p.Name));
var selectorProperties = new HashSet<string>(selectorType.GetProperties().Select(p=> p.Name));

// Get the rule map for the current types
var ruleMap = config.RuleMap;
var typeTuple = new TypeTuple(entityType, selectorType);
ruleMap.TryGetValue(typeTuple, out var rule);

foreach (var selectorProperty in selectorProperties)
{
if (entityProperties.Contains(selectorProperty)) continue;
// Check whether the adapter config has a config for the property
if (rule != null && rule.Settings.Resolvers.Any(r => r.DestinationMemberName.Equals(selectorProperty))) continue;
throw new Exception($"Property {selectorProperty} does not exist in {entityType.Name} and is not configured in Mapster");
}
return source.Adapt<TDestination>(config);
}
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "<Pending>")]
Expand Down

0 comments on commit 7445200

Please sign in to comment.