2010-11-27 6 views
0

C#でASP.NET MVC 2アプリケーションを構築していますが、Automapperを使用してViewModelとビジネスオブジェクト間で値をマップすることに成功しました。オートマップを使用してメソッドにマップ

いくつかの明示的なプロパティに加えて、ビジネスオブジェクトは、明示的に定義されていないプロパティのすべてをキャッチとして辞書をラップします。似た何か:私のViewModelで

public class MyBusinessObject { 
    public void SetExtraPropertyValue<T>(string key, T value) { 
     // ... 
     } 
    public T GetExtraPropertyValue<T>(string key, T defaultValue) { 
     // ... 
     } 
} 

は、私は私が望む任意のプロパティを作成する自由を持っているが、私は、ビジネス・オブジェクトを変更することはできません。

class MyViewModel { 
    public string CustomProp { get; set; } 
} 

と私は格納および取得する値は

businessModelInstance.SetExtraPropertyValue("CustomProp", newVal); 

businessModelInstance.GetExtraPropertyValue("CustomProp"); 

を使用する必要があります:

それでは、私はこのようなビューモデルを作成しましょう私は両方向に行くのに問題があります。
まず、MyBusinessObjectからMyViewModelに行くとき、私は私のカスタムAutomapperプロファイルで行うのは簡単であるべきと思った。他の特性があるものの

CreateMap<MyBusinessObject, MyViewModel>() 
    .ForMember(dest => dest.CustomProp, 
      opt => opt.MapFrom(s => s.GetExtraPropertyValue("CustomProp", ""))); 

しかし、MyBusinessObject.CustomPropは、取り込まれることはありません。
第2に、MyViewModel.CustomPropからMyBusinessObject.SetExtraPropertyValueに値を取得するように設定する方法がわかりません。

  • これを実現する方法はAutomapperでマッピングしますか。
  • 私は が試しているはずの全く異なる攻撃がありますか?
  • コントローラで手動マッピングに頼らなければなりませんか?例えば、MyBusinessObject.SetExtraPropertyValue("CustomProp", MyViewModel.CustomProp)


UPDATE:ここでは@Patrickスティールの提案に基づいて私の解決策は次のとおりです。 私は余分なプロパティキーにマッピングしたいビューモデルのプロパティにカスタム属性を追加しました。カスタムTypeConverterは、リフレクションを使用してこれらの属性を検索し、プロパティを適切にマップします。

public class ItemExtraPropertyConverter : ITypeConverter<MyViewModel, MyBusinessObject> 
{ 
    public MyBusinessObject Convert(ResolutionContext context) 
    { 
     var destination = context.DestinationValue as MyBusinessObject; 
     if (destination == null) 
      throw new InvalidOperationException("Destination type is not of type MyBusinessObject"); 

     foreach (var property in context.SourceType.GetProperties()) 
      foreach (var attribute in property.GetCustomAttributes(true).OfType<ExtraPropertyAttribute>()) 
      { 
       var key = attribute.Key; 
       if (string.IsNullOrEmpty(key)) 
        key = property.Name; 
       destination.SetExtraPropertyValue(key, property.GetValue(context.SourceValue, null)); 
      } 

     return destination; 
    } 
} 

public class ExtraPropertyAttribute : Attribute 
{ 
    public ExtraPropertyAttribute() 
    { 
    } 
    public ExtraPropertyAttribute(string key) 
    { 
     Key = key; 
    } 

    public string Key { get; set; } 
} 

public class MyViewModel 
{ 
    [ExtraProperty] 
    public string CustomProp { get; set; } 

    [ExtraProperty("OtherPropertyValue")] 
    public string CustomProp2 { get; set; } 
} 

カスタムプロファイルクラスのconfigureメソッドで:

CreateMap<MyViewModel, MyBusinessObject>() 
      .ConvertUsing<ItemExtraPropertyConverter>(); 

答えて

0

私の推測では、何かがあなたのGetExtraPropertyValueとSetExtraPropertyValueの実装に問題があるということです。私は簡単なテストを一緒に投げた、あなたが上記で提供したマッピングは期待通りに働いた。テストに使用した実装は次のとおりです。

+0

時間をかけていただきありがとうございます。あなたが正しい、簡単なテストは私のために働いた。私のコードで何か愚かでなければならない - それは私がデバッグできるものです。私にとって大きな問題は、ビュー・モデルのプロパティーをビジネス・オブジェクトの適切なディクショナリー・エントリーにマッピングすることです。私はまだ解決策を思い付くことができませんでした...そこに任意のアイデア? – jaminto

+1

私はそれのためにカスタムタイプコンバータの仕事が働くと思います。ビューのモデルに公開されているすべてのプロパティを照会するための少しのリフレクション。 SetPropertyValueを呼び出すためのキーとしてプロパティ名を使用します。反射には影響がありますが、それが許容できるかどうかを判断する必要があります。 – PatrickSteele

+0

これは大量のサイト(管理サイト)ではないので、反射は問題ではありません。正しい方向に私を指してくれてありがとう。 – jaminto