Add overload to MapPropertiesTo with supplied factory method

This commit is contained in:
Daniel Cronqvist 2024-09-05 21:02:34 +02:00
parent 612b5cdb33
commit 53907b9c36

View file

@ -38,6 +38,14 @@ public interface IHasProperties
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
T MapPropertiesTo<T>() where T : new(); T MapPropertiesTo<T>() where T : new();
/// <summary>
/// Maps all properties in this object to a new instance of the specified type using reflection.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="initializer"></param>
/// <returns></returns>
T MapPropertiesTo<T>(Func<T> initializer);
} }
/// <summary> /// <summary>
@ -78,15 +86,14 @@ public abstract class HasPropertiesBase : IHasProperties
} }
/// <inheritdoc/> /// <inheritdoc/>
public T MapPropertiesTo<T>() where T : new() public T MapPropertiesTo<T>() where T : new() => CreateMappedInstance<T>(GetProperties());
{
var properties = GetProperties();
return CreateMappedInstance<T>(properties);
}
private static object CreatedMappedInstance(Type type, IList<IProperty> properties) /// <inheritdoc/>
public T MapPropertiesTo<T>(Func<T> initializer) => CreateMappedInstance(GetProperties(), initializer);
private static object CreatedMappedInstance(object instance, IList<IProperty> properties)
{ {
var instance = Activator.CreateInstance(type) ?? throw new InvalidOperationException($"Failed to create instance of '{type.Name}'."); var type = instance.GetType();
foreach (var prop in properties) foreach (var prop in properties)
{ {
@ -118,7 +125,7 @@ public abstract class HasPropertiesBase : IHasProperties
break; break;
case ClassProperty classProp: case ClassProperty classProp:
var subClassProp = type.GetProperty(prop.Name); var subClassProp = type.GetProperty(prop.Name);
subClassProp?.SetValue(instance, CreatedMappedInstance(subClassProp.PropertyType, classProp.GetProperties())); subClassProp?.SetValue(instance, CreatedMappedInstance(Activator.CreateInstance(subClassProp.PropertyType), classProp.GetProperties()));
break; break;
case EnumProperty enumProp: case EnumProperty enumProp:
var enumPropInClass = type.GetProperty(prop.Name); var enumPropInClass = type.GetProperty(prop.Name);
@ -133,5 +140,8 @@ public abstract class HasPropertiesBase : IHasProperties
return instance; return instance;
} }
private static T CreateMappedInstance<T>(IList<IProperty> properties) where T : new() => (T)CreatedMappedInstance(typeof(T), properties); private static T CreateMappedInstance<T>(IList<IProperty> properties) where T : new() =>
(T)CreatedMappedInstance(Activator.CreateInstance<T>() ?? throw new InvalidOperationException($"Failed to create instance of '{typeof(T).Name}'."), properties);
private static T CreateMappedInstance<T>(IList<IProperty> properties, Func<T> initializer) => (T)CreatedMappedInstance(initializer(), properties);
} }