MapsterMapper / Mapster

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

Mapster.Tool (Fluent) || Ignore all properties *Except* explicitly configured #512

Open jeffward01 opened 1 year ago

jeffward01 commented 1 year ago

Hello all,

I looked here and did not see the option for this, I also reviewed the Issues and don't think this has been asked before.

I saw this issue that was similar, but the issue was about Mapping, and not code generation: https://github.com/MapsterMapper/Mapster/issues/159

Goals:

Example:

I have a Domain Entity with many properties, such as below:


public class BookDomain : Entity<Guid>
{
    private string _title;
    private string _subTitle;
    private DateTime _publishedDate;

    // Constructor
    public BookDomain() { }

    public string Title => this._title;
    public string SubTitle => this._subTitle;
    public DateTime PublishedDate => this._publishedDate;
}

public abstract partial class Entity<TKey> : IGeneratesDomainEvents, IEntity<TKey>, IEntity
    where TKey : IComparable<TKey>, IEquatable<TKey>
{
    private readonly ConcurrentQueue<IDomainEvent> _domainEvents = new();

    private DateTime _createdAt;

    private DateTime _deactivatedAt;

    private DateTime _deletedAt;

    private DateTime _modifiedAt;

    public abstract object[] GetKeys();

     public TKey? Id { get; }

    public bool IsActive { get; }

    public bool IsDeactivated { get; }

    public bool IsSoftDeleted { get; }

    public bool IsDeactivatedAndDeleted { get; }

    public bool HasPrimaryKey => this.IsTransient.IsFalse();

    public abstract bool IsTransient { get; }

    public DateTime? SoftDeletedAtUtc =>
        this._deletedAt.Equals(default) ? default : this._deletedAt;

    public DateTime CreatedAtUtc => this._createdAt.Equals(default) ? default : this._createdAt;

    public DateTime? DeactivatedAtUtc =>
        this._deactivatedAt.Equals(default) ? default : this._deactivatedAt;

    public DateTime ModifiedAtUtc => this._modifiedAt.Equals(default) ? default : this._modifiedAt;

    public TKey CreatedByUserId { get; }

    public TKey? DeletedByUserId { get; }

    public TKey? DeactivatedByUserId { get; }

    public TKey? ModifiedByUserId { get; }

    public void MarkCreate(TKey createdByUserId, DateTime? utcDateTime = null) { }

    public void MarkDeactivate(TKey deactivatedByUserId, DateTime? utcDateTime = null) { }

    public void MarkSoftDelete(TKey deletedByUserId, DateTime? utcDateTime = null) { }

    public void MarkModified(TKey modifiedByUserId, DateTime? utcDateTime = null) { }

    public void ClearDomainEvents()
    {
        this._domainEvents.Clear();
    }

    public int GetRaisedDomainEventCount()
    {
        return this._domainEvents.Count;
    }

    public IEnumerable<IDomainEvent> GetAllDomainEvents()
    {
        return this._domainEvents;
    }

    public async IAsyncEnumerable<IDomainEvent> GetAllDomainEventsAsync(
        [EnumeratorCancellation] CancellationToken cancellationToken = default
    )
    {
        await foreach (
            IDomainEvent domainEvent in this._domainEvents
                .ToAsyncEnumerable()
                .WithCancellation(cancellationToken)
        )
        {
            yield return domainEvent;
        }
    }

    protected internal virtual void RaiseDomainEvent(IDomainEvent domainEvent)
    {
        this._domainEvents.Enqueue(domainEvent);
    }
}
config.AdaptTo("[name]Dto")
    .ForType<BookDomain>(cfg => {
        cfg.Ignore(poco => poco.LastName);
    });

Is there a way that I can ignore all properties except for a few?

Example:

I only want Book.Title and Book.PublishedData to be mapped:

// Is this possible?
config.AdaptTo("[name]Dto")
    .ForType<BookDomain>(cfg => {
        cfg.Map(poco => poco.Title);
        cfg.Map(poco => poco.PublishedDate);
    });

// Expected ouput:

public class BookDomainDto
{
  public string Title {get; set;}
  public DateTime PublishedDate{get; set;}
}

I can write custom methods for this of course.. but I would prefer something that is built into the library.

Thanks, I hope this makes sense.

Very cool library!

andrerav commented 1 year ago

@jeffward01 Can you take a look at #69 and see if that is something that might work for you?