2009-11-03 73 views
12

一直在使用automapper存在一些實際問題。我想我已經找到了解決方案,但不確定如何實施它。使用帶有WCF服務的CreateMap和Map的實例版本?

基本上我使用了ResolveUsing和ConstructedBy的自定義映射來傳入參數給構造函數,我知道大多數人在global.asax中設置了一次,並忘記了它。

但問題是,我的方法(在WCF)通過在不同PARAMS到ResolveUsing的構造......

我用的是Mapper.CreateMap和Mapper.Map這是前靜態方法,看起來當不同的請求通過方法(多用戶)進入wcf服務時,它們彼此衝突。

看完某些東西后,我可以使用CreateMap和Map的實例版本,以便每個請求都可以獲得自己的地圖,並且可以傳入自己的參數。

但我似乎無法找到如何去做。任何人都可以解釋嗎?我真的卡...

之前,我會得到重複的關鍵錯誤,並且我在構造函數中放了一個日誌跟蹤,它似乎是1請願覆蓋另一個 - 因此靜態版本的Mapper。

嗯,我希望我是正確的,但我無法找到任何東西...

編輯 - 什麼我有

基本上所有映射工作,因爲它應該爲例,由於我在大多數情況下使用MapFrom。

然後,我創建了一個我在URL中傳遞的Resolver實例。在我通過它之前我已經檢查了網址,它的正確性。但是一旦它返回,它將返回錯誤的URL。

我需要在URL中傳遞的原因是它有變量在那裏,所以我需要替換變量...基本上有2個網址取決於辦公室,我到處都有日誌,我可以看到我是什麼通過,但一旦我通過它 - 這不是我通過的,如果這是有道理的,這很奇怪!

它的一個WCF服務和一個客戶端已經在兩個不同的辦公室調用兩次不同的辦公室,因此有兩個不同的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)) 
      ; 

FOUND在哪裏失敗 - 但不明所以

見我的意見內嵌代碼。在構造函數中,urlTemplate到達,我將它保存在一個私有變量中,然後在重寫的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模板,我把它作爲一個集合上的每個記錄(源)上的屬性...並且它的工作原理是完美的。

當然,這真的是補丁,並不理想,但它讓我運行。

我哪裏錯了?

+0

在您的例子是,你不知道的源,直到運行時但你知道你在編譯時映射到什麼目標? – 2009-11-03 17:57:02

+0

不,我知道源...但我傳遞變量ResolveUsing使用構造函數,因此地圖需要每次創建,不需要被任何其他會話共享等 – 2009-11-03 18:13:06

+0

如果這是一個WCF服務它運行在它的自己的應用程序域,所以地圖不會與任何其他進程共享。這聽起來像ResolveUsing的參數有所不同,但ResolveUsing通常採用源類型。你有什麼理由將參數傳遞到你的源類型之外的自定義值解析器的構造函數中? – 2009-11-03 18:35:38

回答

2

那麼看來我的問題是被遺棄的,但很長一段時間玩耍後我終於找到了一個很好的修復..

基本上我是一個解決內,我有另外的地圖,屬性的一個叫另一個ResolveUsing ...

看起來似乎有這個問題。另一個奇怪的是,每當應用程序池啓動或回收時,它都會失敗。因此,它第一次失敗,直到發生了回收(我正在使用wcf應用程序)。

所以我更換了第二映射與一個foreach,做我的映射像我原來的解決內...

我已經把答案在這裏情況下,它可以幫助任何人在將來別人..

我所用的映射靜態方法做我的映射,這些人不是在Global.asax中,我需要通過不同的事情取決於某些因素..

我總是在想,如果有可能做到這一點與實例版本的mappper,我雖然它存在.....但從未發現..

但無論如何,所有的工作,現在100%......

+0

你能否回答http://stackoverflow.com/questions/9498962/contract-first-soa-designing-business-domain-wcf? – Lijo 2012-02-29 16:28:12

1

你看過使用接收目標對象的Map調用嗎?

var bar = new Bar(「Custom Custom Call」);

Mapper.Map(foo,bar);

+0

感謝jimmy,不確定我我很明白。如果我改變了地圖,那麼我將無法訪問我所需要的標準src對象,因爲我通常只需要在幾個屬性上進行映射,這些屬性需要我調用特殊的ResolveUsing並傳遞一個參數,因爲這裏有相當多的這裏的邏輯...所以在解決使用我仍然使用我的標準src對象,但在返回之前應用額外的邏輯(在這種情況下stringg) - 我誤解你了嗎? – 2009-11-03 20:54:20

+0

如果你能詳細說明我會非常感激。 – 2009-11-03 21:03:23

+0

我想我誤解了 - 你有一小段代碼展示了你如何使用CreateMap和Map調用? – 2009-11-04 13:19:19

34

是的,有使用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>() 
+20

我不知道舊版本的AutoMapper,但是在當前版本中,'Configuration'類被命名爲'ConfigurationStore'。 – 2012-11-21 09:15:06

+2

而'AllMappers()'方法現在是一個名爲'Mappers'的屬性。 – bugged87 2015-02-09 20:14:36

13

在迴應較新的語法Luke Woodwardscomment

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>();