MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.25k stars 326 forks source link

Added ValidateAndAdapt Methods for Property Validation #641

Open haritha99ch opened 9 months ago

haritha99ch commented 9 months ago

This PR introduces two new extension methods, ValidateAndAdapt, for the Mapster library. These methods ensure that all properties in the destination type either exist in the source type or are configured in Mapster. If a property does not exist and is not configured, an exception is thrown.

The PR includes:

Usage

public static class ReportSelectors
{

    #region Selectors

    /// <summary>
    ///     Select WitnessId
    /// </summary>
    /// <returns>new <see cref="PermissionsToEditProps" />{ WitnessId = report.WitnessId }</returns>
    public static readonly Expression<Func<Report, PermissionsToEditProps>> PermissionsToEdit =
        e => e.ValidateAndAdapt<Report, PermissionsToEditProps>();

    /// <summary>
    ///     Select ModeratorId, Status
    /// </summary>
    /// <returns>new <see cref="PermissionsToModerateProps" />{ ModeratorId = report.ModeratorId, Status = report.Status }</returns>
    public static readonly Expression<Func<Report, PermissionsToModerateProps>> PermissionsToModerate =
        e => e.ValidateAndAdapt<Report, PermissionsToModerateProps>();

    /// <summary>
    ///     Select WitnessId, Status
    /// </summary>
    /// <returns>new <see cref="PermissionsToViewProps" />{ WitnessId = report.WitnessId, Status = report.Status }</returns>
    public static readonly Expression<Func<Report, PermissionsToViewProps>> PermissionsToView =
        e => e.ValidateAndAdapt<Report, PermissionsToViewProps>(PermissionsToViewPropsAdapter.Config);

    #endregion

    #region Selector Properties

    public record PermissionsToEditProps(WitnessId WitnessId);

    public record PermissionsToModerateProps(ModeratorId? ModeratorId, Status Status);

    public record PermissionsToViewProps(WitnessId WitnessId, WitnessDto Witness, Status Status)
    {
        /// <summary>
        ///     Adapter Settings for <see cref="Witness" />
        /// </summary>
        internal static readonly TypeAdapterSetter<Witness, WitnessDto> WitnessDtoAdapter =
            TypeAdapterConfig<Witness, WitnessDto>.NewConfig()
                .Map(s => s.WitnessId, e => e.Id);
    }

    #endregion

    #region Adapter Settings

    /// <summary>
    ///     Adapter Settings for <see cref="PermissionsToViewProps" />
    /// </summary>
    private static readonly TypeAdapterSetter<Report, PermissionsToViewProps> PermissionsToViewPropsAdapter =
        TypeAdapterConfig<Report, PermissionsToViewProps>.NewConfig()
            .Map(s => s.WitnessId, e => e.WitnessId)
            .Map(s => s.Witness,
                e => e.Witness!.ValidateAndAdapt<Witness, WitnessDto>(PermissionsToViewProps.WitnessDtoAdapter.Config));

    #endregion

}
DocSvartz commented 8 months ago

Hello @haritha99ch Is this a PR, about adding a new feature, or do you want to solve some existing problem? For example: Unexpected null or default value in TDisitination after adaptation?

haritha99ch commented 8 months ago

Hello @DocSvartz I’m not entirely sure if there are existing validations in the library. If there are, then this is just an alternative solution to a problem. However, if there aren’t any validations, this could be considered as a new feature. I just wanted to share a fix, and I hope this can certainly be improved.

DocSvartz commented 8 months ago

This is a great addition. You mentioned RecordType in the description. And I wanted to make sure that the starting point for this PR was not any mapping problems to RecordType.

haritha99ch commented 8 months ago

Thank you for your feedback @DocSvartz. and yes, this is not any mapping problems to RecordType.