0

I use DTO class in API layer and I struggle to map DTO class to "model" class in generic Repository.cs in core layer.

Repository.cs :

namespace DTOMap.Core.Repository.Generic
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private DTOMapContext _context;
        private DbSet<T> _table;
        private IMapper _mapper;
        public Repository(DTOMapContext context)
        {
            _context = context;
            _table = _context.Set<T>();
            var config = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<MyMapper>();
            });
            _mapper = config.CreateMapper();
        }
        public T Add(T obj)
        {
            // Here how to use My Mapper to save a book or an author generically
            // Sth like :
            // temp = _table.Add(_mapper.Map<T>(obj)); Here I want to map Dto to model to save in the db
            // return = (_mapper.Map<T>(temp)); Here I want to map Model to DTO to collect it in API
            // but I can't have a reference to TDTO
            throw new NotImplementedException();
        }
    }
}

I show you the other classes that I find useful (I only implement Add function for this example and I am a beginner in .Net) :

Author.cs

namespace DTOMap.Core.Models
{
    [Table("Author")]
    internal class Author
    {
        [Key]
        public int id { get; set; }
        [Required, MaxLength(255)]
        public string firstName { get; set; }
        [Required,MaxLength(255)]
        public string lastName { get; set; }
    }
}

Book.cs

namespace DTOMap.Core.Models
{
    [Table("Book")]
    internal class Book
    {
        [Key]
        public int id { get; set; }
        [Required,MaxLength(255)]
        public string name { get; set; }
        [Required]
        public int authorId { get; set; }
        [Required]
        public Author author { get; set; }
    }
}

AuthorDTO.cs

namespace DTOMap.Domain.DTO
{
    public class AuthorDTO
    {
        public int id { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
    }
}


BookDTO.cs

namespace DTOMap.Domain.DTO
{
    public class BookDTO
    {
        public int id { get; set; }
        public string name { get; set; }
        public int authorId { get; set; }
        public AuthorDTO author { get; set; }
    }
}


IRepository.cs

namespace DTOMap.Domain.Interface
{
    public interface IRepository<T>
    {
        T Add(T obj);
    }
}

MyMapper.cs

namespace DTOMap.Core
{
    public class MyMapper : Profile
    {
        public MyMapper()
        {
            CreateMap<Book, BookDTO>();
            CreateMap<BookDTO, Book>();
            CreateMap<Author, AuthorDTO>();
            CreateMap<AuthorDTO, Author>();
        }
    }
}

program.cs


... Some Fcts
builder.Services.AddTransient<IRepository<BookDTO>, BookRepository>();
builder.Services.AddTransient<IRepository<AuthorDTO>, AuthorRepository>();
... Some Fcts

If you need any other information, please ask me.

Rena
  • 30,832
  • 6
  • 37
  • 72
antoine_d
  • 27
  • 4
  • There are non generic `Map` overloads. – Lucian Bargaoanu Jul 25 '22 at 14:02
  • Think twice what do you really need a generic repository for? – Serge Jul 25 '22 at 14:22
  • I would argue, that a repository shouldn't return a DTO. The mapping should be done outside of the repository. For generic mappings take a look at https://automapper.org/ – keuleJ Jul 26 '22 at 06:47
  • @keuleJ Ok, but why I shouldn't ? and where should I implement It ? – antoine_d Jul 26 '22 at 07:15
  • Hi @antoine_d, for your Repository add method, what if you use code:`return _mapper.Map(obj); `? From the comment you write, `temp` here is not a model. – Rena Jul 26 '22 at 07:46
  • I finally put DTO pattern in service layer, we use API with DTO data and when we access to the core layer we use model data – antoine_d Jul 27 '22 at 07:47

0 Answers0