Использование Automapper для сопоставления собственных ссылок - PullRequest
6 голосов
/ 13 апреля 2019

У меня есть самореферентные отношения с участием .NET Core ApplicationUser:

public class Network
{
    public ApplicationUser ApplicationUser { get; set; }
    public string ApplicationUserId { get; set; }
    public ApplicationUser Follower { get; set; }
    public string FollowerId { get; set; }
}

Это позволяет вести список «подписчиков» и «подписчиков» в модели пользователя:

public class ApplicationUser : IdentityUser
{
    //...
    public ICollection<Network> Following { get; set; }
    public ICollection<Network> Followers { get; set; }
}

Я использую Automapper для сопоставления подписчиков и отслеживаемых списков с моделью представления. Вот видовые модели:

public class UserProfileViewModel
{
    //...
    public IEnumerable<FollowerViewModel> Followers { get; set; }
    public IEnumerable<NetworkUserViewModel> Following { get; set; }
}

public class NetworkUserViewModel
{
    public string UserName { get; set; }
    public string ProfileImage { get; set; }
    public bool IsFollowing { get; set; } = true;
    public bool IsOwnProfile { get; set; }
}

public class FollowerViewModel
{
    public string UserName { get; set; }
    public string ProfileImage { get; set; }
    public bool IsFollowing { get; set; } = true;
    public bool IsOwnProfile { get; set; }
}

Чтобы учесть различные способы отображения подписчиков и подписчиков, мне пришлось создать два идентичных класса: NetworkUserViewModel и FollowerViewModel, чтобы логика сопоставления Automapper могла различать, как отображать подписчиков и как отображать подписчиков. , Вот профиль отображения:

         CreateMap<Network, NetworkUserViewModel>()
         .ForMember(x => x.UserName, y => y.MapFrom(x => x.ApplicationUser.UserName))
         .ForMember(x => x.ProfileImage, y => y.MapFrom(x => x.ApplicationUser.ProfileImage))
         .ReverseMap();

        CreateMap<Network, FollowerViewModel>()
        .ForMember(x => x.UserName, y => y.MapFrom(x => x.Follower.UserName))
        .ForMember(x => x.ProfileImage, y => y.MapFrom(x => x.Follower.ProfileImage))
        .ReverseMap();

        CreateMap<ApplicationUser, UserProfileViewModel>()
          .ForMember(x => x.UserName, y => y.MapFrom(x => x.UserName))
          .ForMember(x => x.Followers, y => y.MapFrom(x => x.Followers))
          .ForMember(x => x.Following, y => y.MapFrom(x => x.Following))
          .ReverseMap();

Вы можете видеть, что подписчики отображаются как .MapFrom(x => x.Follower.UserName)), а подписчики отображаются как .MapFrom(x => x.ApplicationUser.UserName)).

У меня вопрос: могу ли я определить различные способы отображения подписчиков и подписчиков, не задавая дубликаты классов? Я бы предпочел использовать NetworkUserViewModel для последователей и ; так что мне не нужен дубликат FollowerViewModel, если это возможно. Есть ли способ сделать это?

Обновление

Я реализовал предложение @Matthijs (см. Первый комментарий) использовать наследование, чтобы избежать ненужного дублирования свойств. Теперь мои view-модели:

public class UserProfileViewModel
{
    //...
    public IEnumerable<FollowerViewModel> Followers { get; set; }
    public IEnumerable<FollowingViewModel> Following { get; set; }
}

public class NetworkUserViewModel
{
    public string UserName { get; set; }
    public string ProfileImage { get; set; }
    public bool IsFollowing { get; set; }
    public bool IsOwnProfile { get; set; }
}

public class FollowingViewModel : NetworkUserViewModel
{
}

public class FollowerViewModel : NetworkUserViewModel
{
}

Со следующим изменением логики Automapper:

         CreateMap<Network, FollowingViewModel>()
         .ForMember(x => x.UserName, y => y.MapFrom(x => x.ApplicationUser.UserName))
         .ForMember(x => x.ProfileImage, y => y.MapFrom(x => x.ApplicationUser.ProfileImage))
         .ReverseMap();

        CreateMap<Network, FollowerViewModel>()
        .ForMember(x => x.UserName, y => y.MapFrom(x => x.Follower.UserName))
        .ForMember(x => x.ProfileImage, y => y.MapFrom(x => x.Follower.ProfileImage))
        .ReverseMap();

        CreateMap<ApplicationUser, UserProfileViewModel>()
          .ForMember(x => x.UserName, y => y.MapFrom(x => x.UserName))
          .ForMember(x => x.Followers, y => y.MapFrom(x => x.Followers))
          .ForMember(x => x.Following, y => y.MapFrom(x => x.Following))
          .ReverseMap();

Этот рефактор уменьшает дублирование и упрощает логику отображения.

Я оставляю это открытым на несколько дней на случай, если найдется решение, основанное исключительно на логике Automapper ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...