ZorgoZ
ZorgoZ

Reputation: 3567

Ignoring common properties for multiple mappings with Maspter

I have several types that have some properties in common that need to be ignored when adapted. For this purpose, I made the following code:

internal static class Ext
{
    private static readonly TypeAdapterConfig omitAssetId = new();

    static Ext()
    {
        omitAssetId.NewConfig<IAssetDependent, IAssetDependent>()
            .Ignore(x => x.Id, x => x.AssetId)
            ;

        omitAssetId.NewConfig<IOptionalAssetDependent, IOptionalAssetDependent>()
            .Ignore(x => x.Id, x => x.AssetId)
            ;

        omitAssetId
            .ForType<IAssetDependent, IAssetDependent>()
            .IgnoreMember((member, side) => member.Type.HasAncestor<Asset>());

        omitAssetId
            .ForType<IOptionalAssetDependent, IOptionalAssetDependent>()
            .IgnoreMember((member, side) => member.Type.HasAncestor<Asset>());
    }

    public static void Map<T, TKey>(this ICollection<T> source, T newItem, Func<T, TKey> keyGetter)
        where TKey : IEquatable<TKey>
    {
        if (newItem is null) return;

        var found = source.FirstOrDefault(x => keyGetter(x).Equals(keyGetter(newItem)));

        if (found is null)
            source.Add(newItem);
        else
            newItem.Adapt(found, typeof(T), typeof(T), omitAssetId);
    }
}

Evidently, all my classes I use the extension method on are either IAssetDependent or IOptionalAssetDependent descendants. My goal is not to overwrite the Id (which seems to be working), the AssetId, and, eventually, if it has any Asset descendant reference as well - that too should be spared.

Unfortunately, both the AssetId and the Asset-typed properties are overwritten.

I have put a breakpoint inside the IgnoreMemeber lambda, but it is not hit. Although the AI says that Mapster should work with interfaces (originally I tried <object, object>), I guess that it doesn't.

So how can I make Adapting not to overwrite those properties? Do I need to add each type to the configuration, or is there a more generic way?

[Update]

Reflection-based addition works, but I am still looking for a more generic way, if there is any.

foreach (var type in typeof(IAssetDependent).Assembly.GetExportedTypes().Where(x => x.HasAncestor<IAssetDependent>() || x.HasAncestor<IOptionalAssetDependent>()))
{
    omitAssetId.ForType(type, type)
        .IgnoreMember((member, side) => member.Type.HasAncestor<Asset>())
        .IgnoreMember((member, side) => member.Name == nameof(IAssetDependent.Id))
        .IgnoreMember((member, side) => member.Name == nameof(IAssetDependent.AssetId))
        ;
}

Upvotes: 0

Views: 15

Answers (0)

Related Questions