6

ValueInjecterを使用して、ドメイン モデルからサービス レイヤー経由で提供される DTO にプロパティをマップしています。問題のサービスは更新も受け入れます...そのため、更新された DTO が渡され、これがドメイン オブジェクトに注入されて保存されます。

    // 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 Proxy クラスにより、値インジェクターが国の型と一致しなくなりますか? 平坦化中に機能するため、これは意味がありません。
  • おそらく、何らかの理由で非平坦化が発火していないのでしょう。つまり、Dto は CountryCode であり、ドメインは Country.Code です。

Dto で CountryCode プロパティを使用して countryService.LookupCode を呼び出し、更新プログラムの挿入中に使用する正しいオブジェクトを返す必要があります。

4

3 に答える 3

3

非平坦化はこれを行うことです:

entity.Country.Code <- dto.CountryCode

必要なものは次のとおりです。

entity.Country <- dto.CountryCode

したがって、解決策は、CountryCode から Country に移動する ExactValueInjection を継承することです。

私がお勧めするのは、私の別のプロジェクトのライブデモで行ったのと同じことですhttp://awesome.codeplex.com

私はこのようなものを持っています:

    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;}
    }

これらのインジェクションを使用して、エンティティから 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からだけでなく処理しますか? への往復だけでなく、エンティティを継承する他のタイプ

于 2011-01-24T18:20:25.850 に答える
3

Omu からの提案/参照を使用すると、これが問題の特定のコードでした。

 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;
}
于 2011-01-26T04:07:26.713 に答える
0

setter メソッドを呼び出すフレームワークですか? ほとんどの DI フレームワークでは、標準は setMethod() の小文字の「s」です。あくまで初見のおすすめ。

于 2011-01-24T14:53:53.503 に答える