12

オートマッパーでいくつかの実際の問題が発生しています。私は解決策を見つけたと思いますが、それを実装する方法がわかりません。

基本的に、私は ResolveUsing と ConstructedBy でカスタム マッピングを使用してパラメーターをコンストラクターに渡しています。ほとんどの人がこれを global.asax で一度設定して忘れていることを理解しています。

しかし、問題は、(wcf 上の) 私のメソッドが異なるパラメーターを ResolveUsing のコンストラクターに渡すことです ......

静的メソッドである Mapper.CreateMap と Mapper.Map を使用する前に、さまざまな請願がメソッド (マルチユーザー) を介して wcf サービスに入ると、互いに競合しているように見えます。

何かを読んだ後、CreateMap と Map のインスタンス バージョンを使用して、個々の請願が独自のマップを取得し、独自のパラメーターを渡すことができるように見えます。

しかし、私はそれを行う方法を見つけることができないようです。誰か説明してくれませんか?私は本当に立ち往生しています...

以前は重複キー エラーが何度も発生し、コンストラクターにログ トレースを記録したところ、一方の請願がもう一方の請願を上書きしているように見えたので、静的バージョンの Mapper が作成されました。

私が正しいことを願っていますが、他に何も見つかりません...

編集済み - 私が持っているものの例

ほとんどの場合MapFromを使用しているため、基本的にすべてのマッピングは正常に機能しています。

次に、URL で渡すリゾルバーのインスタンスを作成します。渡す前にURLを確認しましたが、正しいです。しかし、返されると、間違った URL が返されます。

URL を渡す必要がある理由は、そこに変数があるため、変数を置き換える必要があるためです... 基本的に、オフィスに応じて 2 つの URL があり、どこにでもログがあり、何を渡しているかを確認できますが、一度私はそれを渡します - それは私が渡したものではありません。

その WCF サービスとクライアントは、2 つの異なるオフィスでメソッドを 2 回呼び出したため、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 が到着し、それをプライベート変数に保存し、オーバーライドされた 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

一時的な解決策

一時的な解決策を実行しましたが、本当に悪いです。オートマッパーは私が試みていることを実行できると確信していますが、明らかに何か間違ったことをしています。

基本的に、LINQ を介してレコードのコレクション (THIS IS MY SOURCE) を返すので、正しい URL テンプレートを持つすべてのレコードに新しいフィールドを入力しました。そして、(コンストラクターを介して)urlテンプレートを渡す代わりに、コレクション(THE SOURCE)のすべてのレコードのプロパティとして利用できるようにしました...そしてそれは完璧に機能します。

もちろん、これは実際にはパッチであり、理想的ではありませんが、実行できます。

どこが間違っていますか?

4

5 に答える 5

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>()
于 2011-09-11T18:29:54.463 に答える
13

新しい構文に関するLuke Woodwardsコメントに応えて:

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>();
于 2013-06-12T00:35:18.987 に答える
2

私の質問は放棄されたようですが、しばらく遊んだ後、最終的に良い修正を見つけました..

基本的に私はResolveの中にいて、プロパティの1つが別のResolveUsingを呼び出した別のMAPがありました...

これには問題があるようです。もう1つの奇妙なことは、アプリケーションプールが開始またはリサイクルされるたびに失敗したことです..したがって、最初は失敗し、リサイクルが発生するまでは問題ありませんでした(私はwcfアプリを使用しています)。

そこで、2 番目のマッピングを foreach に置き換え、元の Resolve 内でそのようなマッピングを行いました ...

将来他の誰かを助けることができる場合に備えて、ここに答えを入れました..

私はマッパー静的メソッドを使用してマッピングを行っていましたが、特定の要因に応じて異なるものを渡す必要があるため、これらはglobal.asaxにはありませんでした..

マッパーのインスタンスバージョンでそれを行うことができるかどうか、私はいつも疑問に思っていました..

とにかく、すべてが100%機能しています...

于 2009-11-06T16:52:51.457 に答える
1

宛先オブジェクトを取得する Map 呼び出しの使用を見たことがありますか?

var bar = new Bar("各呼び出しをカスタマイズ");

Mapper.Map(foo, bar);

于 2009-11-03T20:30:31.577 に答える
1

Automapper で Mapper のインスタンス バージョンを使用する場合は、MappingEngine クラスを使用できると思います。私は、静的な Mapper クラスが MappingEngine オブジェクトをインスタンス化して構成し、すべての重要なマッピング作業を行うと信じています。

Automapper に IoC を適用する例を次に示します (MappingEngine のインスタンス化が必要です)。

http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/05/11/automapper-and-ioc.aspx

于 2010-10-12T02:43:12.670 に答える