2011-01-24 12 views
6

ドメインモデルのプロパティをサービスレイヤを介して提供されるDTOにマップするのにValueInjecterを使用しています。問題のサービスも更新を受け付けます...更新されたDTOが渡され、これがドメインオブジェクトに注入されて保存されます。値インジェクタ:Dto to Domain Model(NHibernate)

// Domain 
    public class Member 
    { 
     public Country Country { get; set; } 
    } 

    public class Country 
    { 
     public string Code { get; set; } 
     public string Name { get; set; } 
    } 

    //Dto 
    public class MemberDto 
    { 
     public string CountryCode { get; set; } 
    } 

    //Transformation Method attempt 1 
    public Member InjectFromDto (MemberDto dto, Member source) 
    { 
     source = source.InjectFrom<UnflatLoopValueInjection>(dto); 
     return source; 
    } 

上記のすべてのコードは、私が必要とするものではない明らかにProperty Member.Country.Codeの更新です。ドキュメントからそう

は、私がオーバーライドを作成するために必要な考え出し、これを得た:

public class CountryLookup: UnflatLoopValueInjection<string, Country> 
    { 
     protected override Country SetValue(string sourcePropertyValue) 
     { 
      return countryService.LookupCode(sourcePropertyValue); 
     } 
    } 


//revised transformation call 
//Transformation Method attempt 2 
    public Member InjectFromDto (MemberDto dto, Member source) 
    { 
     source = source.InjectFrom<UnflatLoopValueInjection>(dto) 
         .InjectFrom<CountryLookup>(dto); 
     return source; 
    } 

私の問題はCountryLookupが呼び出されることは決してありません、デバッグ中です。私は考えることができる

考えられる理由:

  • 国の型と一致しないために値の挿入器を引き起こしてNHibernateのプロキシクラス?これは平坦化中に機能するため意味がありません。
  • おそらく、何らかの理由で非平坦化が起こっていない可能性があります。すなわちDTOは、国番号とドメインがCountry.Code

である私は、更新の注入の際に使用する正しいオブジェクトを返すようにcountryService.LookupCodeを呼び出すためにDTO上のCountryCodeプロパティを使用する必要があります。

+0

あなたが達成しようとしていることを教えてください。最初の試みは機能しますが、必要なものではありません。何が必要ですか? – Omu

+0

CountryLookupという名前のあなたのインジェクションは、stringからCountryへのunflatを意味します。つまり、string型のCountryCodeから値を取得し、それを国番号 – Omu

+0

のCountry.Codeに入れます@Omu thats correct Country Country:Country :USA、Name:United States}と私のDtoはCountryCodeで渡します: "CA"はCountry.CodeプロパティをCAに設定し、 'Name'プロパティを米国のままにします。前もって設定されたドメインオブジェクトを更新していることを思い出してください...これにより、正しいCountryオブジェクトを検索するためにcountryServiceを呼び出す必要があります。私はDtoから 'Code'を取得し、そのコードを使用して正しいCountryオブジェクトを検索します。 – Galen

答えて

3

を継承する任意の他のタイプ。

public class CountryLookup : ExactValueInjection 
    { 
     private ICountryService countryservice; 

     public CountryLookup(ICountryService countryService) 
     { 
      this.countryService = countryService; 
     } 

     protected override bool TypesMatch(Type s, Type t) 
     { 
      return (s == typeof(string)) && (t == typeof (Country)); 

     } 
     protected override Object SetValue(object v) 
     { 
      if (v == null) 
       return null; 

      var country = countryService.LookupCode((string) v); 
      return country; 
     } 

     public override string SourceName() 
     { 
      return "CountryCode"; 
     } 

     public override string TargetName() 
     { 
      return "Country"; 
     }  
    } 

public Member InjectFromDto (MemberDto dto, Member source) 
{ 
    source = source.InjectFrom<UnflatLoopValueInjection>(dto) 
        .InjectFrom<CountryLookup>(dto); 
    return source; 
} 
+1

はい、これはうまくいくはずです(コンストラクタパラメータICountryServiceをどこに設定するかはわかりませんが)。私はあなたにもっと一般的な方法、すべての注入を見てほしかった – Omu

+0

コンストラクタパラメータはCastle Windsor依存性注入。それは実際のルックアップサービスコールがそれほど関連しないので、ソリューションのための少しのミュートポイントです。 – Galen

+0

また、あなたの提案を使用して、このプロジェクトの汎用ソリューションを検討していきます。 – Galen

0

セッターメソッドを呼び出すフレームワークはありますか?ほとんどのDIフレームワークでは、標準はsetMethod()の小文字の 's'です。ちょうど最初に考えられた推薦。

+0

SetValueメソッドを参照していますか?その場合、それはValueInjecterフレームワークの一部です。 – Galen

+0

ニック、これはJavaではなく.NETです。.NET標準はメソッド名のパスカルケースです。ラクダケースではありません。 – Phill

3

unflatteningがこれを行うために、次のようになりますあなたが必要なもの

entity.Country.Code <- dto.CountryCode 

されています:

entity.Country <- dto.CountryCode 

ので、あなたのためのソリューションは、あなたが国番号から国へ行くだろうExactValueInjectionを継承することです。

public class Entity 
    { 
     public int Id{get;set;} 
    } 
    public class Member : Entity 
    { 
     public Country Country{get;set;} 
    } 
    public class MemberDto : DtoWithId 
    { 
     public int? Country {get;set;} 
    } 

およびこれらを使用します。私はあなたがを行うことをお勧めします何

は私、私はこのような何かを持っているhttp://awesome.codeplex.com

の別のプロジェクトのライブデモでは、私がやったのと同じ操作を行うですエンティティからdtoに戻るための注射

public class NullIntToEntity : LoopValueInjection 
     { 
      protected override bool TypesMatch(Type sourceType, Type targetType) 
      { 
       return sourceType == typeof(int?) && targetType.IsSubclassOf(typeof(Entity)); 
      } 

      protected override object SetValue(object sourcePropertyValue) 
      { 
       if (sourcePropertyValue == null) return null; 
       var id = ((int?) sourcePropertyValue).Value; 

       dynamic repo = IoC.Resolve(typeof(IRepo<>).MakeGenericType(TargetPropType)); 

       return repo.Get(id); 
      } 
     } 
//(you also need to have a generic repository, notice IRepo<>)  
    public class EntityToNullInt : LoopValueInjection 
     { 
      protected override bool TypesMatch(Type sourceType, Type targetType) 
      { 
       return sourceType.IsSubclassOf(typeof (Entity)) && targetType == typeof (int?); 
      } 

      protected override object SetValue(object o) 
      { 
       if (o == null) return null; 
       return (o as Entity).Id; 
      } 
     } 

これらの注射は、 intから? 及び背面にも、これは問題に固有のコードであったOMUから提案/参照を使用してエンティティ

+0

このコメントは私の問題の具体的な答えにつながりますが、正確な答えはわかりません。これが参考になりましたか? – Galen

関連する問題