2016-06-01 9 views
1

他のパラメータに基づいて、セットアップにみとめプロパティを関数を実行します。私のコードは簡略化されていますが、それはポイントを取得します。 Property3使用AutoMapperは、私はAutoMapperはこれを行うことができますかどうかを確認するために助けが必要

public class SourceObject 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
    public string Property3 { get; set; } 

} 

public class DestinationObject 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
    public string Property3 { get; set; } 
    public string Property4 { get; set; } 
    public string Property5 { get; set; } 
    public string Property6 { get; set; } 
} 

var vm = new ViewModel 
{ 
    Objects = Mapper.Map<IList<SourceObject>, IEnumerable<DestinationObject>>(dests) 
}; 

foreach (var destObj in vm.Objects) 
{ 
    Utility.SetupProperties(destObj, new AnotherDependency(), destObj.Property3, 
     someFlag, anotherFlag); 
} 

Property1現在AutoMapperによって設定されています。私はその後、機能をProperty6に設定Property4からDestinationObjectsのリストをループにいくつかの追加のフラグを持っています。私はこれがAutoMapperが使われているものではないかもしれないと理解していますが、私は実際にオブジェクトを2回ループしないようにしたいと思います。静的なSetupProperties関数は他の場所でも使用されていますので、そのまま使用していきたいと思います。 AutoMapperでこれを設定できますか?事前に助けてくれてありがとう。

+0

あなたが使用することができます[前そして、 'SourceObject'と' DestinationObject'間のマップ上のアクション](https://github.com/AutoMapper/AutoMapper/wiki/Before-and-after-map-actions)の後? – AGB

+0

お返事ありがとうございます。 MindingDataのように提案されていますが、残念ながら、BeforeアクションとAfterアクションを使用してマッピングに追加のパラメータを渡すことはできません。 – Will

答えて

0

それは本当にUtility.SetupProperties内部で何が起こっているかによって異なりますが、前とAutomapperでアクションをマッピングした後使用することにより、ロジックのビットは、より複雑なマッピングの状況を持つことが可能です:通常https://github.com/AutoMapper/AutoMapper/wiki/Before-and-after-map-actions

Mapper.Initialize(cfg => { 
    cfg.CreateMap<SourceObject, DestinationObject>() 
    .BeforeMap((src, dest) => 
    { 
     //Do some work here and set properties. 
    }) 
}); 
+0

お返事ありがとうございます。 SetupPropertiesは入力を見て残りのプロパティを決定します。私はマッピングの前後の動作について読んでいますが、実行時に追加のフラグを渡すことはできないと思いますか? – Will

+0

それは本当です。そして、あなたは残念ながらそれを行うことができません(私が知る限り)。これを行うには、Mapper.Mapに「params」入力が必要です。追加のフィールドについて考慮する必要があります。 – MindingData

0

、あなたは(第2のwikiの例のように)あなたが閉鎖経由で渡したいAfterMapとキャプチャどんな追加パラメータを使用することができます。しかし、あなたはコレクション間で変換を行っているので、私はこの場合アイテムごとにそれを行うためのきれいな方法はないと思います。

私はいくつかの掘削を行ってきた、と私はあなたがしようとしている変換を達成するためにITypeConverter<TSource, TDestination>を使用することができると思います。

私はなど、実装上のいくつかの推測を行うと、Utility.SetupPropertiesのための例を使用していたが、私はコンセプトコンソールアプリケーションの以下の証明は、カスタム変換を実現する方法を示すべきだと思う:

using System; 
using System.Collections.Generic; 
using AutoMapper; 

namespace ConsoleApplication 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var sourceObjects = new SourceObject[] { 
       new SourceObject{Property1 = "prop 1A"}, 
       new SourceObject{Property2 = "Prop 2B"}, 
       new SourceObject{Property3 = "Prop 3C"}}; 

      var someFlag = true; 
      var anotherFlag = false; 

      Mapper.Initialize(cfg => 
      { 
       cfg.CreateMap<SourceObject, DestinationObject>().ConvertUsing<CustomConverter>(); 
      }); 

      var vm = new ViewModel 
      { 
       Objects = Mapper.Map<IList<SourceObject>, IEnumerable<DestinationObject>>(sourceObjects, opts => 
       { 
        opts.Items.Add("AnotherDependency", new AnotherDependency { Foo = "bar" }); 
        opts.Items.Add("flag1", someFlag); 
        opts.Items.Add("flag2", anotherFlag); 
       }) 
      }; 

      foreach (var obj in vm.Objects) 
      { 
       Console.WriteLine($"[{obj.Property1}, {obj.Property2}, {obj.Property3}, {obj.Property4}, {obj.Property5}, {obj.Property6}]"); 
      } 
     } 
    } 

    public class CustomConverter : ITypeConverter<SourceObject, DestinationObject> 
    { 
     public DestinationObject Convert(ResolutionContext context) 
     { 
      return Convert(context.SourceValue as SourceObject, context); 
     } 

     public DestinationObject Convert(SourceObject source, ResolutionContext context) 
     { 
      var dest = new DestinationObject 
      { 
       Property1 = source?.Property1, 
       Property2 = source?.Property2, 
       Property3 = source?.Property3 
      }; 

      var items = context.Options.Items; 

      Utility.SetupProperties(dest, 
       items["AnotherDependency"] as AnotherDependency, 
       dest.Property3, 
       items["flag1"] as bool? ?? false, 
       items["flag2"] as bool? ?? false); 

      return dest; 
     } 
    } 

    public static class Utility 
    { 
     public static void SetupProperties(DestinationObject x, AnotherDependency ad, string a, bool b, bool c) 
     { 
      x.Property4 = ad.Foo; 
      if (b || c) 
      { 
       x.Property5 = ad?.ToString() ?? a; 
      } 
      if (b && c) 
      { 
       x.Property6 = ad?.ToString() ?? a; 
      } 
      return; 
     } 
    } 
    public class ViewModel 
    { 
     public IEnumerable<DestinationObject> Objects { get; set; } 
    } 
    public class AnotherDependency { public string Foo { get; set; } } 
    public class SourceObject 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
    } 
    public class DestinationObject 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
     public string Property4 { get; set; } 
     public string Property5 { get; set; } 
     public string Property6 { get; set; } 
    } 
} 
+0

時間をとっていただきありがとうございます。私は間違いなくこれを試して返信/受け入れます!再度、感謝します! – Will

+0

ねえ、幸運?私が逃したものはありますか? – AGB

+0

申し訳ありませんが、まだ試してみる機会はありませんでした。私はそうした後、私は間違いなく戻ってきます。再度、感謝します! – Will

関連する問題