title: Map nested elements to related lists using AutoMapper
body: <p>I have two sets of objects</p>
  
  <p>Objects that I use in C# client application:</p>
  
  <pre><code>public class EmployeeClient
  {
      public int Id { get; set; }
  
      public int DepartmentId { get; set; }
  
      public string FirstName { get; set; }
  
      public string LastName { get; set; }
  
      public string MiddleName { get; set; }
  }
  
  public class DepartmentClient
  {
      public int Id { get; set; }
  
      public string Name { get; set; }
  }
  
  public class OrganizationClient
  {
      public int Id { get; set; }
  
      public string Name { get; set; }
  
      public List&lt;DepartmentClient&gt; Departments { get; set; }
  
      public List&lt;EmployeeClient&gt; Employees { get; set; }
  }
  </code></pre>
  
  <p>And DTOs:</p>
  
  <pre><code>public class EmployeeDto
  {
      public int Id { get; set; }
  
      public string FirstName { get; set; }
  
      public string LastName { get; set; }
  
      public string MiddleName { get; set; }
  }
  
  public class DepartmentDto
  {
      public int Id { get; set; }
  
      public string Name { get; set; }
  
      public List&lt;EmployeeDto&gt; Employees { get; set; }
  }
  
  public class OrganizationDto
  {
      public int Id { get; set; }
  
      public string Name { get; set; }
  
      public List&lt;DepartmentDto&gt; Departments { get; set; }
  }
  </code></pre>
  
  <p>I use AutoMapper and I need to configure mapping Client -> DTOs and DTOs -> Client.
  I implemented mapping DTOs->Client like this:</p>
  
  <pre><code>public class DtoToClientMappingProfile: Profile
  {
      public DtoToClientMappingProfile()
      {
          CreateMap&lt;EmployeeDto, EmployeeClient&gt;();
  
          CreateMap&lt;DepartmentDto, DepartmentClient&gt;();
  
          CreateMap&lt;OrganizationDto, OrganizationClient&gt;()
              .ForMember(dest =&gt; dest.Employees, opt =&gt; opt.ResolveUsing(src =&gt; src.Departments.SelectMany(d =&gt; d.Employees)))
              .AfterMap(AfterMap);
      }
  
      private void AfterMap(OrganizationDto dto, OrganizationClient client)
      {
          foreach (var department in dto.Departments)
          {
              foreach (var employee in department.Employees)
              {
                  var clientEmployee = client.Employees.First(e =&gt; e.Id == employee.Id);
                  clientEmployee.DepartmentId = department.Id;
              }
          }
      }
  }
  </code></pre>
  
  <p>It is not universal solution, but is works for me.</p>
  
  <p>I've found only one option how mapping Client->DTOs could be implemented:</p>
  
  <pre><code>public class ClientToDtosMappingProfile : Profile
  {
      public ClientToDtosMappingProfile()
      {
          CreateMap&lt;EmployeeClient, EmployeeDto&gt;();
  
          CreateMap&lt;DepartmentClient, DepartmentDto&gt;();
  
          CreateMap&lt;OrganizationClient, OrganizationDto&gt;()
              .AfterMap(AfterMap);
      }
  
      private void AfterMap(OrganizationClient client, OrganizationDto dto)
      {
          foreach (var employee in client.Employees)
          {
              var departmentDto = dto.Departments.First(d =&gt; d.Id == employee.DepartmentId);
              if (departmentDto.Employees == null)
              {
                  departmentDto.Employees = new List&lt;EmployeeDto&gt;();
              }
  
              var configuration = (IConfigurationProvider)new MapperConfiguration(cfg =&gt;
              {
                  cfg.AddProfiles(typeof(ClientToDtosMappingProfile));
              });
  
              var mapper = (IMapper)new Mapper(configuration);
  
              var employeeDto = mapper.Map&lt;EmployeeDto&gt;(employee);
              departmentDto.Employees.Add(employeeDto);
          }
      }
  }
  </code></pre>
  
  <p>It works, but I do not like this solution because I should create instance of new Mapper every time I map objects. In my real code Employee has a lot of nested elements and mapping is configured in multiple profiles.</p>
  
  <p>Any ideas how it could be implemented better?</p>