Blocks in Episerver implement the IContent
interface only during runtime
which makes using AutoMapper difficult.
A few weeks ago I started using AutoMapper in an Episerver (.NET CMS) project to map models to view models semi-automatically.
My initial feelings: 😻
It was quite nice until I started creating mappings for blocks (reusable pieces of content).
My feelings now: 😿😾
Whereas page models implement Episerver's IContent
interface "normally,"
block models implement the IContent
interface only during runtime.
This means that
creating a mapping from IContent
to a block type is not possible.
At least not possible in this way that I tried:
// Base view model for pages and blocks
public interface IContentViewModel
{
string ContentLink { get; set; }
string ContentType { get; set; }
// etc.
}
public class IContentProfile : Profile
{
public IContentProfile()
{
CreateMap<IContent, IContentViewModel>();
}
}
public class MyPageViewModel : IContentViewModel
{
// ...
}
public class MyPageProfile : Profile
{
public MyPageProfile()
{
CreateMap<MyPage, MyPageViewModel>()
// `MyPage` implements `IContent`, so this is ok:
.IncludeBase<IContent, IContentViewModel>();
}
}
public class MyBlockViewModel : IContentViewModel
{
// ...
}
public class MyBlockProfile : Profile
{
public MyBlockProfile()
{
CreateMap<MyBlock, MyBlockViewModel>()
// Error! `MyBlock` doesn't implement `IContent` until runtime,
// so this doesn't work:
.IncludeBase<IContent, IContentViewModel>();
}
}
I eventually came up with a solution, but it feels very complex and very verbose.
I don't know if AutoMapper should be this difficult. If you are working on an Episerver project, my suggestion would be to research alternative mappers or do mappings manually.