Search code examples
c#automapperautomapper-5

AutoMapper mapping interface and ignoring column


I have the following code:

Interfaces

namespace Core.Interfaces
{
    public interface ILoanApplicationBase
    {
        string ContactName { get; set; }
        string Email { get; set; }
    }
}

namespace App1.Core.Interfaces
{
    public interface ILoanApplication : ILoanApplicationBase
    {
        Guid? Id { get; set; }

        List<ILoanApplicationDebt> LoanApplicationDebts { get; set; }

        ILoanApplicationStatus LoanApplicationStatus { get; set; }

        IReadOnlyCollection<IBusinessBorrower> BusinessBorrowers { get; set; }
    }
}

namespace App2.Core.Interfaces
{
    public interface ILoanApplication : IDomainModel, ILoanApplicationBase
    {
        int? Id { get; set; }

        IReadOnlyCollection<ILoanApplicationDebt> LoanApplicationDebts { get; set; }

        ILoanApplicationStatus LoanApplicationStatus { get; set; }

        IReadOnlyCollection<IBusinessBorrower> BusinessBorrowers { get; set; }
    }
}

Objects

namespace App1.Domain
{
    [Serializable]
    public class LoanApplication : ILoanApplication
    {
        public Guid? Id { get; set; }

        public List<ILoanApplicationDebt> LoanApplicationDebts { get; set; }

        public LoanApplicationStatus LoanApplicationStatus { get; set; }

        public IReadOnlyCollection<IBusinessBorrower> BusinessBorrowers { get; set; }

    }
}

namespace App2.Domain
{
    [Serializable]
    public class LoanApplication : ILoanApplication
    {
        public override int? Id { get; set; }

        public int? LoanApplicationStatusId { get; set; }

        public virtual LoanApplicationStatus LoanApplicationStatus { get; set; }

        ILoanApplicationStatus ILoanApplication.LoanApplicationStatus
        {
            get
            {
                return (ILoanApplicationStatus)LoanApplicationStatus;
            }
            set
            {
                LoanApplicationStatus = (LoanApplicationStatus)value;
            }
        }

        public virtual ICollection<LoanApplicationDebt> LoanApplicationDebts { get; set; }

        IReadOnlyCollection<ILoanApplicationDebt> ILoanApplication.LoanApplicationDebts
        {
            get
            {
                List<ILoanApplicationDebt> loanApplicationDebts = new List<ILoanApplicationDebt>();
                foreach (ILoanApplicationDebt loanApplicationDebt in this.LoanApplicationDebts)
                {
                    loanApplicationDebts.Add(loanApplicationDebt);
                }
                return loanApplicationDebts;
            }
            set
            {
                foreach (var item in value)
                {
                    this.LoanApplicationDebts.Add((LoanApplicationDebt)item);
                }
            }
        }

        public ICollection<BusinessBorrower> BusinessBorrowers { get; set; }

        IReadOnlyCollection<IBusinessBorrower> ILoanApplication.BusinessBorrowers
        {
            get
            {
                List<IBusinessBorrower> businessBorrowers = new List<IBusinessBorrower>();
                foreach(BusinessBorrower businessBorrower in BusinessBorrowers)
                {
                    businessBorrowers.Add((IBusinessBorrower)businessBorrower);
                }
               return new ReadOnlyCollection<IBusinessBorrower>(businessBorrowers);

            }
            set
            {

                foreach (IBusinessBorrower businessBorrower in value)
                {
                    BusinessBorrowers.Add((BusinessBorrower)businessBorrower);
                } 
            }
        }
    }
}

My goal is to use Automapper to copy over the common properties from between the two versions of LoanApplication. I have the following working:

Mapper.Initialize(cfg => cfg.CreateMap<App1.Domain.LoanApplication, App2.Domain.LoanApplication>()
    .ForMember(x => x.Id, opt => opt.Ignore())
    .ForMember(x => x.LoanApplicationStatus, opt => opt.Ignore())
    .ForMember(x => x.BusinessBorrowers, opt => opt.Ignore())
    .ForMember(x => x.LoanApplicationDebts, opt => opt.Ignore()));

app2LoanApplication = Mapper.Map<LoanApplication>(app1LoanApplication);

This copies all the columns over correctly, but I still have to manually update the ignored properties.

The types for ID are different, so I always want to ignore. But wanted to know is how I can also map LoanApplicationStatus, BusinessBorrowers and LoanApplicationDebts. I didn't post those definitions to cut down on space, but just like LoanApplicaiton, the App1 version uses Guid and App2 uses Int for Ids. Each version share the same base class, but have a few different columns added.


Solution

  • I figured it out, I needed to add additional mappings per object:

    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<App1.Domain.LoanApplication, App2.Domain.LoanApplication>()
            .ForMember(x => x.Id, opt => opt.Ignore())
    
        cfg.CreateMap<App1.Domain.BusinessBorrower, App2.Domain.BusinessBorrower>()
            .ForMember(x => x.Id, opt => opt.Ignore())
    
        cfg.CreateMap<App1.Domain.LoanApplicationDebt, App2.Domain.LoanApplicationDebt>()
            .ForMember(x => x.Id, opt => opt.Ignore());
    });