Форум программистов, компьютерный форум, киберфорум
C#: ASP.NET Core
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/29: Рейтинг темы: голосов - 29, средняя оценка - 4.93
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60

Инициализация AutoMapper

04.02.2018, 12:40. Показов 5924. Ответов 18

Студворк — интернет-сервис помощи студентам
Здравствуйте. Создаю ASP.NET MVC проект, с трехслойной архитектурой (DataAccess, BusinessLogic, PresentationLayer). В BusinessLogic есть DTO сущности для передачи данных из DAL в PresentationLayer, в котором, в свою очередь есть ViewModel'и для передачи данных в представления. Для маппинга данных из одних сущностей на другие использую AutoMapper v6.2.2. В PresentationLayer, в Global.asax (в Application_Start()) вызываю
C#
1
2
3
4
5
    Mapper.Initialize(cfg => 
                                  {
                                   cfg.CreateMap<SomeViewModel, Some_DTO>();
                                   ///..............                                   
                                   }
для маппинга сущностей BLL и PresentationLayer;
Вопрос: где производить CreateMap<> для сущностей DAL и BLL? Если еще раз вызвать Mapper.Initialize(cfg => ..... в слое BLL, То будет исключение :

Mapper already initialized. You must call Initialize once per application domain/process.

В Global.asax (в Application_Start()) в слое PresentationLayer я не могу вызвать cfg.CreateMap<SomeDALEntity, Some_DTO>(), поскольку в PresentationLayer придется дабавлять ссылку на DAL, что делает бессмысленным многослойную архитектуру приложения. Заранее спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.02.2018, 12:40
Ответы с готовыми решениями:

Для чего нужен Automapper?
Всем привет. Помогите по проекту. хочу разобраться: 3) Для чего нужен Automapper?

Automapper map func predicate error
Доброе утро, при маппинге предиката имею ошибку AutoMapper (8.1.0) Unmapped members were found. Review the types and members...

ASP.NET Core: не работает метод Update EF после Automapper
Собственно вот. При сохранении записи в базу данных выдает исключение, что данный экземпляр объекта не отслеживается. Поле Id не имеет...

18
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
04.02.2018, 12:56
Цитата Сообщение от plusok Посмотреть сообщение
где производить
В DAL и производите. Каждый объект репозитория создает маппинг на свой сырой объект из Dal. (Из Data Model, то бишь на сущность из базы).

Цитата Сообщение от plusok Посмотреть сообщение
в котором, в свою очередь есть ViewModel'и
ViewModel-и должны быть частью BLL, поскольку это тоже модели. Просто модели для представлений. По-хорошему вы можете просто подменять ваш Presentation Logic Layer (winforms, wpf, консольку), скармливая вьюхам
одни и те же вью модели из BLL. Поскольку вью-модели не зависят от вьюх.
0
 Аватар для sau
2773 / 2073 / 386
Регистрация: 22.07.2011
Сообщений: 7,820
04.02.2018, 13:01
Каждый слой ничего не знает о вышележащих слоях , значит , если слою BLL нужен Mapper для DAL модели . он вправе его использовать , так же как и PresentationLayer не обязан понимать что творится внутри BLL , т.е так же вправе вызвать Mapper моделей BLL на свои модели представления. Но , раз уж Mapper такой себе singleton , наверняка есть возможность проверить была ли инициализация и сбросить ее.

Добавлено через 2 минуты
Цитата Сообщение от IamRain Посмотреть сообщение
ViewModel-и должны быть частью BLL, поскольку это тоже модели.
позволю себе не согласиться , BLL и логика интерфейса - разные вещи , кроме того BLL может использоваться в сервисах где вообще интерфейсом и не пахнет , т.е никаких ViewModel там быть не должно.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
04.02.2018, 13:11
Цитата Сообщение от sau Посмотреть сообщение
BLL и логика интерфейса - разные вещи
Я понимаю, что разные. Но логика интерфейса - это движущая сила для любого приложения, то есть она определяет все основные workflow в приложении.
Если стоит задача сменить графическую платформу, при этом все воркфлоу остаются теми же самыми (например, при переходе от десктопа на веб), то получается надо заново писать вьюмодели для веба? - Логично, что не надо этого делать. Ведь вьюмодели не должны зависеть от вьюх, поэтому пихаем вьюмодели в BLL. Повторюсь, это ведь тоже модели.

Добавлено через 1 минуту
Цитата Сообщение от sau Посмотреть сообщение
т.е никаких ViewModel там быть не должно.
В сервисах мы их и не будем попросту использовать. Хотя момент сервисами мне не совсем понятен.
0
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60
04.02.2018, 13:57  [ТС]
IamRain, спасибо вам за участие, но я бы рекомендовал вам почитать что-то на тему SOLID принципов, или вот это https://metanit.com/sharp/mvc5/23.5.php.
sau - по поводу "сбросить инициализацию" - да такая возможность есть, но в доках сказано что методом Reset() не рекомендуется пользоваться "на проде":

Resets the mapper configuration. Not intended for production use, but for testing scenarios.

Та и потом, если например, где-нибудь в BLL его скинуть, то потом в PresentationLayer опять нужно будет инициализировать, а с Global.asax так не получится; а пихать инициализатор еще куда-нибудь в слое PresentationLayer, с , опять-таки проверкой на то, был ли маппер инициализирован ранее - это уже избыток...
Просто не хочется изобретать колесо.... Думаю уже кто-то с подобным сталкивался, хочется какое-то "правильное"решение.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
04.02.2018, 14:17
plusok, насколько я помню в рабочем проекте мы именно в DAL и иницализируем маппинг, причем сразу для всех сущностей из BLL, через рефлексию. + Используется свой convention по именованию сущностей.
Получается, есть базовый класс репозитория, который иницализирует маппинг, а все остальный репозитории от него наследуются.
В любом репозитории маппинг уже на блюдечке, типа того. Вот и все.
0
 Аватар для sau
2773 / 2073 / 386
Регистрация: 22.07.2011
Сообщений: 7,820
04.02.2018, 17:33
Цитата Сообщение от IamRain Посмотреть сообщение
В сервисах мы их и не будем попросту использовать. Хотя момент сервисами мне не совсем понятен.
Бизнес логика обрабатывает какой либо бизнес процесс (или множество ) . например в документообороте этапы рассмотрения , согласования , утверждения документа и т.п.
Естественно , что для каждого этапа безнеспроцесса могут быть разные виды обслуживающих его приложений , со своим пользовательским интерфейсом , или без него - в случае каких либо фоновых процессов/сетевых сервисов , решающих свой круг задач в рамках общего бизнеспроцесса. , но при этом все они взаимодействуют через общую бизнес логику.
По этому и вью.моделей будет множество для разных UI , если есть общая вью.модель она может быть вынесена в доменную для UI , а BLL тем временем живет своей жизнью и ей совершенно по барабану какие у нее клиенты в виде тех или иных приложений уровня пользователя. Короче , UI модель обслуживает конкретный тип интерфейса. и должна располагаться в ближайшим к нему слое. (архитектуру UI так же можно подразделить на несколько локальных слоев , тот же MVP обеспечит общий подход в логике UI как для веба так и для десктопа , но это не значит что этот слой нужно помещать в BLL)

Добавлено через 6 минут
Но логика интерфейса - это движущая сила для любого приложения, то есть она определяет все основные workflow в приложении.
Нет , она лишь является точкой взаимодействия пользователя с тем или иным workflow , но никак не определяет его правила работы. Наоборот , интерфейс подчиняется правилам worklow , и более того , может лишь частично представлять доступ к его более широкому функционалу , в рамках своего предназначения.


Т.е я понимаю бизнес процесс и его логику - как некое большое облако различных сервисов , к которым может подключиться пользователь с помощью того или иного UI , и тот или иной UI имеет свою логику взаимодействия с пользователем - чисто в плане как управлять кнопочками и т.п (не без оглядки на логику BL) , ну и соответствующую вспомогательную UI модель.
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
04.02.2018, 17:42
Цитата Сообщение от sau Посмотреть сообщение
Короче , UI модель обслуживает конкретный тип интерфейса.
sau, ну почему же, не пойму я никак? Я проецирую DAL, BLL, Presentation Logic Layer на MVVM.
Зачем для каждой View писать View Model? View Model не зависит от View-хи, на то она и ViewModel.
Допустим, спроектировали наше большое приложение. Сформировали основные use case-ы, в одном из use case-ов определили activity - редактирование данных пользователя (DetailView).
Модели ведь не должны зависеть от вьюх, в этом вы согласны со мной? Так кот зачем при смене UI например с WinForms на ASP MVC переписывать ViewModel? На крайняк, разве что повесить на ViewModel дополнительно описывающие метаданные с помощью атрибутов (одна строка кода во вью-модели - единственное изменение) и все, ничего более.

Добавлено через 5 минут
Цитата Сообщение от sau Посмотреть сообщение
Нет , она лишь является точкой взаимодействия пользователя с тем или иным workflow , но никак не определяет его правила работы
Понятно, что не определяет, но по-хорошему, однажды написанной логики интерфейса (читай ViewModel-и) согласно указанному workflow, будет достаточно, ведь логика взаимодействия определилась? - Да, и она не собирается меняться, она осталась такой же. Соответственно, менять нужно только вьюхи, через которые пользователь взаимодействует с системой.
Вообщем, ключевая фраза - логика взаимодействия пользователя с view не меняется, поэтому не меняется ViewModel, меняется только View.
0
 Аватар для sau
2773 / 2073 / 386
Регистрация: 22.07.2011
Сообщений: 7,820
04.02.2018, 18:00
Цитата Сообщение от plusok Посмотреть сообщение
Та и потом, если например, где-нибудь в BLL его скинуть, то потом в PresentationLayer опять нужно будет инициализировать, а с Global.asax так не получится; а пихать инициализатор еще куда-нибудь в слое PresentationLayer, с , опять-таки проверкой на то, был ли маппер инициализирован ранее - это уже избыток...
Тогда это хренатень не походит , какой вообще смысл делать singleton маппер , когда очевидно это может понадобиться в различных независимых друг от друга местах , а если Вы подключите сборку в проект где этот же самый мапер , все , кранты и сборку не поюзать ? , фигня какая то.

Добавлено через 5 минут
Цитата Сообщение от IamRain Посмотреть сообщение
Зачем для каждой View писать View Model? View Model не зависит от View-хи, на то она и ViewModel.
Вьюмодель не зависит от ее структуры представления в интерфейсе , Вы правы , интерфейс можно и так и эдак рисовать с применением одной модели , но вью.модель в этом случае определяет тип данных интерфейса , а если появляется интерфейс которому эта ViewModel не подходит , у него будет уже другая-своя вью.модель , но при этом оба этих интерфейса обслуживают общий workflow , и в этом случае будем пихать в workflow все возможные виды вью.моделей , которые еще и будут добавляться по мере появления дополнительных вариантов интерфейсов.
Мы же не говорим о монолитном и раз написанном приложении , разделение на слои подразумевает повторное использование в различных местах , где Presentation layer в какой то степени может быть повторно использован , но гораздо в меньшей степени чем BLL или DAL.

Я , например , разработчик api веб.сервиса для BLL , и тут мне в сборке суют какие то ViewModel_и специфичных UI , нахрена они мне в моем rest api сервисе, спрошу я ?

Цитата Сообщение от IamRain Посмотреть сообщение
ведь логика взаимодействия определилась?
определилась в рамках предназначения интерфейса , в рамках круга решаемых им задач , интерфейс может не охватывать весь функционал workflow , а быть лишь маленькой точкой взаимодействия с одним из этапов процесса.
Ладно , я уже повторяюсь , пущай и другими словами , мысль надеюсь донес . дальше сами ).
0
 Аватар для IamRain
4693 / 2701 / 734
Регистрация: 02.08.2011
Сообщений: 7,227
04.02.2018, 18:02
Цитата Сообщение от sau Посмотреть сообщение
а если интерфейс не содержит логин-пароль , у него будет уже другая вью.модель
Логика взаимодействия с пользователем изменилась, так что это уже другая история Ну да ладно, не хочу спорить.
0
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60
04.02.2018, 18:07  [ТС]
Цитата Сообщение от sau Посмотреть сообщение
Тогда это хренатень не походит , какой вообще смысл делать singleton маппер , когда очевидно это может понадобиться в различных независимых друг от друга местах , а если Вы подключите сборку в проект где этот же самый мапер , все , кранты и сборку не поюзать ? , фигня какая то.
Я уже тоже к этому склоняюсь. )) В более ранних версия AutoMapper такого не было (Mapper already initialized. You must call Initialize once per application domain/process.) Наверное нужно глубже погрузится в доку, по любому есть какое-то решение
0
Эксперт .NET
 Аватар для Wolfdp
3789 / 1766 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
04.02.2018, 18:17
Что мешает в Dao/Bll определить класс, выполняющий исключительно инициализацию всех моделе своего уровня с Core интерфейсом, и на входной точке приложения собирать все реализации и вызывать?
0
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60
04.02.2018, 19:35  [ТС]
PresentationLayer ничего не должен знать о DAL
0
 Аватар для Cupko
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,680
Записей в блоге: 1
04.02.2018, 19:48
Цитата Сообщение от plusok Посмотреть сообщение
PresentationLayer ничего не должен знать о DAL
не факт. Onion-архитектура как пример.
0
Эксперт .NET
 Аватар для Wolfdp
3789 / 1766 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
04.02.2018, 22:10
Цитата Сообщение от plusok Посмотреть сообщение
PresentationLayer ничего не должен знать о DAL
Если он не будет о нем знать, то и не сможет с ним работать. Как минимум об интерфейсе

вообще идея такая

- MyApp.Core
C#
1
2
3
4
interface IInitModule
{
  void Init();
}
- MyApp.IDao
C#
1
2
3
4
5
6
interface ISomeDao
{
  List<Some> Get();
}
 
class SomeDto { /* */ }
- MyApp.Dao
C#
1
2
3
4
class SomeDao : ISomeDao
{
  List<SomeDto> Get() { /* */ }
}
- MyApp.Bll
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SomeService
{
  ISomeDao dao;
 
  List<SomeModel> Get() {
    var list = dao.Get();
    return Mapper.Map<SomeModel>(list);
  }
}
 
class InitBll : IInitModule
{
  void Init() {
    Mapper.Initialize(cfg=>cfg.CreateMap<SomeDto, SomeModel>());
  }
}
и где-то в недрах страрта апликейшена
C#
1
2
3
var initModules = container.GetInterfaces<InterfaceType>();
foreach(var module in initModules)
  module.Init();
0
1524 / 510 / 126
Регистрация: 09.01.2018
Сообщений: 1,547
05.02.2018, 11:38
plusok, не знаю зачем вам понабился DTO. При внедрении зависимости проект получает все зависимости проекта от которого он зависит. Т.е. если у вас BLL зависит от DAL, а UI зависит от BLL, UI получит все зависимости BLL и объекты DAL будут доступны на уровне UI. Это ж лишняя работа, лишний репозиторий.
Но если уж надо именно так, то схема следующая. Automapper инициализируется действительно один раз, в StartUp. Пакет его устанавливается в BLL и он будет доступен из UI. В UI устанавливается пакет

AutoMapper.Extensions.Microsoft.Dependen cyInjection

И в StartUp

C#
1
services.AddAutoMapper();
Ну уровнях UI и BLL будет по репозиторию, один возвращает DTO, второй ViewModel. Оба через конструктор получают IMapper. На обоих уровнях прописывается по классу

C#
1
2
3
4
5
6
7
public class OrganizationProfile : Profile
{
     public OrganizationProfile()
        {
            CreateMap<TSource, TDest>(); //конфигурация маппинга конкретных объектов
        }
}
Automapper подхватит профайлы и все отмаппит.

В StartUp прописываете оба репозитория и указываете, что в конструктор обоим следует передать IMapper, который получаете из сервисов.
Ну и все.
1
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60
05.02.2018, 13:29  [ТС]
escoult, спасибо. Вот это похоже.... позже попробую - отпишусь.

Добавлено через 12 минут
Так же , как вариан попробовать инициализацию маппера не статически, а через экземпляры класса MapperConfiguration :

C#
1
2
3
4
5
6
7
8
9
10
var config = new MapperConfiguration(c =>
            {
                c.CreateMap<someDTO, someModel>();
                c.CreateMap<someDTO2, someModelView2>();
              ///.......
            });
            config.AssertConfigurationIsValid();
 
            var mapper = config.CreateMapper();
            var result = mapper.Map<someDTO2, someModelView2>(item);
0
1524 / 510 / 126
Регистрация: 09.01.2018
Сообщений: 1,547
05.02.2018, 14:21
plusok, поправлю сам себя

Цитата Сообщение от escoult Посмотреть сообщение
... и указываете, что в конструктор обоим следует передать IMapper, который получаете из сервисов
Этого не нужно явно указывать. IMapper то уже зарегистрирован. Достаточно только зарегистрировать репозитории. Я что то сразу не подумал об этом.
0
0 / 0 / 2
Регистрация: 11.06.2015
Сообщений: 60
05.02.2018, 15:47  [ТС]
Спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.02.2018, 15:47
Помогаю со студенческими работами здесь

Automapper many to one
Добрый день. Пишу проект на asp.net mvc 5. И часто возникают ситуации когда захожу в тупик, а подсказать не кому, нужен наставник для того...

Automapper и List<T>
Добрый день! Имеется модель и модель представления: public class Student { public int Id { get; set; } ...

AutoMapper - не может споставить данные
Вечером добрый, у меня возникла проблема с работой AutoMapper. у меня есть две сущности: public class UserDTO { ...

AutoMapper error. Как правильно проецировать complex type?
Помогите исправить ошибку The type 'UserPassport' has already been configured as an entity type. It cannot be reconfigured as a complex...

При мапинге automapper-ом many-to-many releation делает множество заявок к базе вместо одной
Добрый день уважаемые форумчане, Подскажите пожалуйста, вот такой вопрос. Я использую automapper для мапинга моделей. Проблема том...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru