Использование версии экземпляра CreateMap и Map с помощью службы WCF?
Имеют некоторые реальные проблемы с automapper. Я думаю, что нашел решение, но не знаю, как его реализовать.
В основном я использую настраиваемое сопоставление с ResolveUsing и ConstructedBy для передачи в params конструктору, я понимаю, что большинство людей задают это в global.asax один раз и забывают об этом.
Но проблема в том, что мой метод (на wcf) проходит в разных параметрах к конструктору ResolveUsing......
До того, как я использовал Mapper.CreateMap и Mapper.Map, которые являются статическими методами, и кажется, что когда различные запросы поступают в службу wcf с помощью методов (multi -user), они конфликтуют друг с другом.
После прочтения чего-то я могу использовать экземплярную версию CreateMap и Map, чтобы каждое отдельное ходатайство получало свою собственную карту и могло передавать свои собственные параметры.
Но я не могу найти, как это сделать. Может ли кто-нибудь объяснить, пожалуйста? Я действительно застрял...
Раньше я получал повторяющиеся ключевые ошибки, а также добавлял трассировку журнала в конструктор, и оказалось, что 1 петиция перезаписывает другую - следовательно, статические версии Mapper.
Надеюсь, я прав, но больше ничего не могу найти...
EDITED - пример того, что у меня есть
В основном все сопоставление работает так, как должно, поскольку я использую MapFrom в большинстве случаев.
Затем я создаю экземпляр моего Resolver, который я передаю в URL. Я проверил URL-адрес, прежде чем передать его и правильно. Но как только он вернется, он вернет неправильный URL.
Причина, по которой мне нужно пройти по URL-адресу, заключается в том, что в нем есть переменные, поэтому мне нужно заменить переменные... В основном есть два URL-адреса в зависимости от офиса, и у меня есть журналы везде, и я вижу, что я прохожу но, как только я передаю его, это не тот, который я прошел, если это имеет смысл, это странно!
Его служба WCF и клиент вызвали метод, дважды проходящий в 2 разных офисах, следовательно, два разных URL-адреса. Но они всегда возвращают один и тот же URL. Он как один сеанс перезаписывает другой...
Надеюсь, это имеет смысл.
SalesPointResolver newSalesPointResolver = new SalesPointResolver(returnReservationUrl, reservationSite.ReservationUrl, startDate, endDate, officeCode);
Mapper.CreateMap<Models.Custom.House, DTO.House>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.TaxIncluded,
opt => opt.MapFrom(src => src.Segments.FirstOrDefault().TaxIncluded))
.ForMember(dest => dest.TaxPercentage,
opt => opt.MapFrom(src => src.Segments.FirstOrDefault().TaxPercentage))
.ForMember(dest => dest.SalesPoints,
opt =>
opt.ResolveUsing(newSalesPointResolver))
;
НАЙДЕН ГДЕ ЕСТЬ НЕИСПРАВНОСТЬ - НО НЕИЗВЕСТНО ПОЧЕМУ
См. мои комментарии в строке с кодом. В конструкторе появляется urlTemplate, я сохраняю его в приватном var, а затем в переопределенном ResolveCore это что-то еще: -)
Я разместил там журналы log4net, поэтому я вижу, что происходит.
[Log]
public class SalesPointResolver : ValueResolver<Models.Custom.House, IList<DTO.SalesPoint>>
{
private readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private string urlTemplate;
public SalesPointResolver (bool returnReservationUrl, string urlTemplate, DateTime startDate, DateTime endDate, string officeCode)
{
this.urlTemplate = urlTemplate;
log.Error("passed in " + urlTemplate); // THIS IS PERFECT
log.Error("I am now " + this.urlTemplate); // THIS IS PERFECT
}
protected override IList<DTO.SalesPoint> ResolveCore(House source)
{
this.house = source;
log.Error("in resolveCore :" + this.urlTemplate); // THIS IS RETURNING THE WRONG VALUE
ВРЕМЕННОЕ РЕШЕНИЕ
Я сделал временное решение, но это действительно плохо. Я уверен, что automapper может делать то, что я пытаюсь, но я, очевидно, что-то не так.
В принципе, я возвращаю через LINQ коллекцию записей (ЭТО МОЙ ИСТОЧНИК), поэтому я ввел новое поле в каждую запись, в которой есть правильный шаблон URL. И затем вместо того, чтобы передавать (через конструктор) шаблон url, я имею его как свойство в КАЖДОЙ записи в коллекции (ИСТОЧНИК)... и он отлично работает.
Конечно, это действительно патч, а не идеальный, но он запускает меня.
Где я иду не так?
Ответы
Ответ 1
Ну, похоже, что мой вопрос оставлен, но после довольно продолжительного разговора я наконец нашел ХОРОШЕЕ решение.
в основном я был внутри Resolve, и у меня была другая MAP, которая из одного из свойств вызывала другое ResolveUsing...
Кажется, что проблема связана с этим. Еще одна странность в том, что она не срабатывала каждый раз, когда пул приложений запускался или перерабатывался. Следовательно, это не удалось в первый раз, а затем было нормально, пока не произошла перезагрузка (я использую приложение wcf).
Итак, я заменил второе сопоставление с помощью foreach и сделал свое сопоставление как внутри моего оригинального Resolve...
Я поставил здесь ответ, если он может помочь кому-либо еще в будущем.
Я использовал статические методы Mapper для своих сопоставлений, они не были в global.asax, поскольку мне нужно передавать разные вещи в зависимости от определенных факторов.
Я всегда задавался вопросом, возможно ли это сделать с версиями экземпляра mappper, хотя он существовал..... но так и не узнал..
Но в любом случае все работает на 100% сейчас...
Ответ 2
Да, есть способ использовать экземплярную версию AutoMapper.
Вместо...
Mapper.CreateMap<Dto.Ticket, Entities.Ticket>()
вы можете использовать:
var configurationStore =
new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);
var mapper = new MappingEngine(configurationStore);
configurationStore.CreateMap<Dto.Ticket, Entities.Ticket>()
Ответ 3
В ответ на Люк Вудвард comment в новом синтаксисе:
ConfigurationStore store
= new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);
store.AssertConfigurationIsValid();
MappingEngine engine = new MappingEngine(store);
//add mappings via Profiles or CreateMap
store.AddProfile<MyAutoMapperProfile>();
store.CreateMap<Dto.Ticket, Entities.Ticket>();
Ответ 4
Посмотрели ли вы на использование вызова Map, который принимает объект назначения?
var bar = new Bar ( "Пользовательский каждый вызов" );
Mapper.Map(foo, bar);
Ответ 5
Если вы хотите использовать экземплярную версию Mapper в Automapper, я думаю, вы можете использовать класс MappingEngine. Я считаю, что статический класс Mapper создает экземпляр и настраивает объект MappingEngine, чтобы выполнить всю работу с грубой картиной nitty.
Вот пример применения IoC к Automapper (который требует создания экземпляра MappingEngine)
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/11/automapper-and-ioc.aspx