82 lines
3.5 KiB
C#
82 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using System.Text;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace AutoMapPropertyHelper
|
|
{
|
|
public interface IAutomappedAttribute
|
|
{
|
|
public virtual object ApplyTo(IServiceProvider? providers, object value) => throw new NotImplementedException();
|
|
public virtual object? ApplyFrom(IServiceProvider? providers, object source) => throw new NotImplementedException();
|
|
public virtual Type GetSourceType() => throw new NotImplementedException();
|
|
}
|
|
public interface IAutomappedAttribute<TSource, TSelf> : IAutomappedAttribute
|
|
{
|
|
object IAutomappedAttribute.ApplyTo(IServiceProvider? providers, object value) => throw new NotImplementedException();
|
|
object? IAutomappedAttribute.ApplyFrom(IServiceProvider? providers, object source) => throw new NotImplementedException();
|
|
Type IAutomappedAttribute.GetSourceType() => throw new NotImplementedException();
|
|
|
|
public TSource ApplyTo(IServiceProvider? providers, TSource value);
|
|
public TSelf ApplyFrom(IServiceProvider? providers, TSource source);
|
|
|
|
public Expression<Func<TSource, TSelf>> GetProjectorFrom(IServiceProvider providers) => throw new NotImplementedException();
|
|
}
|
|
|
|
public interface IPolymorphicResponse<TType, TResponseType> : IAutomappedAttribute<TType, TResponseType>
|
|
{
|
|
public abstract TResponseType GetResponseType(TType entity);
|
|
public abstract Dictionary<Type, LambdaExpression> GetProjectors(IServiceProvider providers);
|
|
|
|
public Expression<Func<TType, TResponseType>> GetCustomProjectorFrom(IServiceProvider providers)
|
|
{
|
|
|
|
// Parameter for the combined lambda
|
|
var parameter = Expression.Parameter(typeof(TType), "x");
|
|
|
|
// Start building the expression tree dynamically
|
|
Expression? resultExpression = null;
|
|
|
|
foreach (var (type, projector) in GetProjectors(providers))
|
|
{
|
|
// Condition: Check if the parameter is of the current type
|
|
var typeCondition = Expression.TypeIs(parameter, type);
|
|
|
|
// Cast the parameter to the current type
|
|
var castedParameter = Expression.Convert(parameter, type);
|
|
|
|
// Invoke the projector with the casted parameter
|
|
var invokeProjector = Expression.Invoke(projector, castedParameter);
|
|
|
|
// Convert the result to the common response type
|
|
var convertedResult = Expression.Convert(invokeProjector, typeof(TResponseType));
|
|
|
|
// Combine with existing conditions (if any)
|
|
resultExpression = resultExpression == null
|
|
? (Expression)convertedResult
|
|
: Expression.Condition(typeCondition, convertedResult, resultExpression);
|
|
}
|
|
|
|
// Fallback for unsupported types
|
|
resultExpression ??= Expression.Constant(null, typeof(TResponseType));
|
|
|
|
// Create the combined lambda
|
|
var combinedProjector = Expression.Lambda<Func<TType, TResponseType>>(resultExpression, parameter);
|
|
|
|
return combinedProjector;
|
|
}
|
|
|
|
public TResponseType ApplyFrom(IServiceProvider? providers, TType source)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public TType ApplyTo(IServiceProvider? providers, TType value)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
}
|