2009-11-03 58 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>();