Как мне сопоставить файлы DTO с моими моделями в моем проекте .Net Core - PullRequest
1 голос
/ 07 марта 2019

Я никогда раньше не работал с проектом .Net Core, но у меня есть история с .Net, включая MVC и инфраструктуру сущностей.Я работаю с новым проектом .Net Core, в котором есть пять папок с решениями: EHA.PROJ.API, EHA.PROJ.DTO, EHA.PROJ.Repository, EHA.PROJ.Repository.Test и EHA.PROJ.Web.В папке EHA.PROJ.DTO есть несколько файлов, таких как CategoryDTO.cs, который выглядит следующим образом:

namespace EHA.PROJ.DTO
{
    public class CategoryDescDTO
    {
        public int CategoryRef { get; set; }

        public string CategoryName { get; set; }
    }
}

Я хочу настроить механизм сопоставления для получения данных из EHA.PROJ.DTO файлы к файлам модели в моей папке моделей в моей папке EHA.PROJ.Web.Я просматривал, поскольку я никогда не делал ничего подобного раньше, так как ранее я работал с данными из папки DAL, используя структуру сущностей и соединение, выполняемое через строки соединения.Я предполагаю, что должен быть какой-то процесс для отображения данных в моем dbContext, чтобы соединить файлы в обеих папках.Я нашел некоторую информацию об AutoMapper, но не знал, как ее реализовать.

Эта договоренность с .Net Core нова для меня, поэтому, если кто-нибудь сможет помочь с любыми примерами или укажет мне правильное направление, я буду благодарен.

Ответы [ 3 ]

0 голосов
/ 07 марта 2019

Ваша первая проблема - ваши сущности в вашем веб-проекте. С самого начала у вас есть тесная связь между веб-проектом и вашим слоем данных, что в значительной степени сводит на нет все остальные ваши уровни: DTO, репозиторий и т. Д. Вы хотите переместить свои сущности и контекст в истинное слой данных (т.е. проект библиотеки классов, отдельный от вашего веб-проекта).

Затем вы хотите решить, насколько далеко должен простираться ваш уровень данных. Если API предназначен для веб-сайта, то вы фактически хотите удалить все зависимости на уровне данных из веб-проекта. Ваш проект DTO будет разделен между API и веб-проектами, а ваш API будет отправлять / получать ваши DTO, сопоставляя их от своих сущностей.

Однако, если вы собираетесь это сделать, тогда проект репозитория должен полностью исчезнуть. Просто пусть ваш API работает напрямую с EF и вашими сущностями. Ваша абстракция - это сам API; нет необходимости в другом. Единственная причина иметь уровень хранилища - это то, что и API, и Web будут напрямую использовать хранилища, что на самом деле не очень хорошая модель. Вы неизбежно получите кучу дублированной логики, характерной для каждого проекта.

Проще говоря, шаблон репозитория является излишним при использовании ORM, такого как EF. ORM - это ваш уровень данных. Вы просто используете DAL, предоставленный третьей стороной, а не тот, который вы создали сами. Шаблон репозитория имеет смысл только при работе напрямую с SQL, используя что-то вроде ADO.NET напрямую. Иначе избавься от этого.

Наличие API - это достаточно абстракция, если ваша цель - просто скрыть слой данных. Веб-сайт ничего не знает о базовом источнике данных, и API - это на самом деле просто сервисный уровень, который возвращает JSON через HTTP, а не экземпляры объектов напрямую, т. Е. API является , по сути, вашим уровнем «хранилища».

Ситуацию можно улучшить еще больше, перейдя на архитектуру на основе микросервисов. При этом у вас по сути есть несколько небольших, автономных API, которые работают только с одной частью вашего домена или частью функциональности. Каждый может использовать EF напрямую, или совершенно другой ORM, или даже совершенно другой стек. У вас могут быть API-интерфейсы, основанные на Node.js или Python и т. Д. Веб-сайт просто отправляет запросы различным службам для получения необходимых данных, и ему неизвестно, как эти службы на самом деле работают.

0 голосов
/ 07 марта 2019

Я уже довольно давно использую Automapper в проектах .NET Core из-за простоты использования и встроенного внедрения зависимостей.

Установка из PM:

Install-Package AutoMapper
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

Зарегистрируйтесь в методе Startup.cs, ConfigureServices:

services.AddAutoMapper(typeof(Startup));

Создайте класс для хранения ваших сопоставлений, например, MappingProfile.cs, используя Profile из automapper,Вы можете определить сопоставления.

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Operator, OperatorDto>().ReverseMap();
    }
}

}

Приведенное выше сопоставление сообщает autopper, что Operator можно сопоставить с OperatorDto, а OperatorDto можно сопоставить с Operator.

В вашем контроллере вы можете ввести IMapper

    private readonly IMapper _mapper;

    public OperatorsController(IMapper mapper)
    {
        _mapper = mapper;
    }

и отобразить значения, как показано ниже:

var dto = _mapper.Map<OperatorDto>(op); // Map op object to dto

var op = _mapper.Map<Operator>(dto); // Map dto to op object

Automapper предлагает настраиваемые сопоставления, если вам это нужно.

Хотя сопоставления с Automapper очень просты, вам нужно изучить основы.

Я считаю, что это того стоитусилия по его изучению, так как это сэкономит вам много времени при написании кода отображения в будущем.

0 голосов
/ 07 марта 2019

Эта статья является хорошим справочным материалом для начала: https://buildplease.com/pages/repositories-dto/

Мое предложение состоит в том, чтобы иметь ассемблер DTO, который отображает вашу модель на объект DTO. Итак, вы начинаете с вашего класса DTO:

namespace EHA.PROJ.DTO
{
    public class CategoryDescDTO
    {
        public int CategoryRef { get; set; }

        public string CategoryName { get; set; }
    }
}

Затем соберите ассемблер:

public class CategoryDescAssembler {
    public CategoryDescDTO WriteDto(CategoryDesc categoryDesc) {
        var categoryDescDto = new CategoryDescDTO();
        categoryDescDto.CategoryRef = categoryDesc.CategoryRef;
        categoryDescDto.CategoryName = categoryDesc.CategoryName;
        return categoryDescDto;
    }
}

Теперь вы реализуете сервис для выполнения всей работы, необходимой для получения объекта DTO:

public class CategoryDescService : ICategoryDescService {
    private readonly IRepository<CategoryDesc> _categoryDescRepository;
    private readonly CategoryDescAssembler _categoryDescAssembler;

    public CategoryDescService(IRepository<CategoryDesc> categoryDescRepository, CategoryDescAssembler categoryDescAssembler) {
        _categoryDescRepository= categoryDescRepository;
        _categoryDescAssembler= categoryDescAssembler;
    }

    public CategoryDescDTO GetCategoryDesc(int categoryRef) {
        var categDesc = _categoryDescRepository.Get(x => x.CategoryRef == categoryRef);
        return _categoryDescAssembler.WriteDto(categDesc);
    }
}

С интерфейсом, похожим на это:

public interface ICategoryDescService
{
    CategoryDescDTO GetCategoryDesc(int categoryRef);
} 

Затем вам потребуется добавить службу в файл Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddTransient<ICategoryDescService, CategoryDescService>();
}

Теперь вы можете позвонить в свою службу с вашего контроллера просмотра.

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