Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Neil Hodges 338 posts 987 karma points
    Oct 12, 2021 @ 11:51
    Neil Hodges
    0

    Using IUmbracoMapper to map custom Models or AutoMapper?

    Hi

    Using Umbraco 8.16

    I'm porting over an old Umbraco v7 site that used AutoMapper heavily.

    I've added AutoMapper to my Class Library and registered in a composer:

     composition.Register<IMapper>(Lifetime.Singleton);
    

    However, I then get an error:

    Missing public constructor for Type: AutoMapper.IMapper

    So should I use AutoMapper or use Umbraco's own IUmbracoMapper?

    I have tried to add this into my SurfaceController:

     private readonly IUmbracoMapper _umbracoMapper;
            public NewsSurfaceController(IUmbracoMapper umracoMapper)
            {
                _umbracoMapper = umracoMapper;
            }
    

    But getting an error where it cannot find IUmbracoMapper (what namesapce is this under? do i need to register via a composer first?). Am I instantiating it correctly here?

  • Neil Hodges 338 posts 987 karma points
    Oct 12, 2021 @ 15:17
    Neil Hodges
    100

    Ok so i think i have sussed this out now:

    In my SurfaceController :

    public ActionResult NewsIndex(int page=0, int pageSize=2)
            {
    
                var newsArticles = _newsRepository.GetAllNewsArticlesFromSource(CurrentPage.Id);
    
                var definitions = new MapDefinitionCollection(new IMapDefinition[]
                {
                    new NewsArticleUmbracoMapperDefinition(_mediaService)
                });
    
                var mapper = new UmbracoMapper(definitions, _scopeProvider);
                var articleViewModels = mapper.Map<List<Data.Entities.NewsArticle>, List<NewsArticleViewModel>>(newsArticles);
    
                var skipCount = (page > 0 && pageSize > 0) ? page * pageSize : 0;
    
                if (articleViewModels.Count < skipCount)
                {
                    skipCount = articleViewModels.Count / pageSize;
                }
    
                var articles = articleViewModels.Skip(skipCount).Take(pageSize);
                var results = new PagedResult<NewsArticleViewModel>(articleViewModels.Count, page, pageSize) { Items = articles }; ;
    
                return PartialView("NewsIndex", results);
            }
    

    I then create a Mapper Definition:

    public class NewsArticleUmbracoMapperDefinition : IMapDefinition
        {
            private readonly IMediaService _mediaService;
    
            public NewsArticleUmbracoMapperDefinition(IMediaService mediaService)
            {
                _mediaService = mediaService;
            }
    
            public void DefineMaps(UmbracoMapper mapper)
            {
                mapper.Define<NewsArticle, NewsArticleViewModel>((source, context) => new NewsArticleViewModel(), Map);
            }
    
            private void Map(NewsArticle source, NewsArticleViewModel target, MapperContext context)
            {
                target.Introduction = source.Introduction;
                target.MenuTitle = source.MenuTitle;
                target.NewsDate = source.NewsDate;
                if (source.NewsImage > 0)
                {
                    target.NewsImageName = _mediaService.GetById(source.NewsImage).Name;
                    target.NewsImageUrl = _mediaService.GetById(source.NewsImage).Path;
                }
                target.Url = source.Url;
            }
        }
    

    Does this look like the correct way of doing it? It seems to work Ok, just want to make sure I'm on the right path with it now.

Please Sign in or register to post replies

Write your reply to:

Draft