Search code examples
nhibernatedtoautomappingvalueinjecter

Value Injecter : Dto to Domain Model (NHibernate)


I am using ValueInjecter to map properties from a Domain model to a DTO served up via a Service Layer. The service in question also accepts updates... so an updated DTO is passed in and this is then injected to the domain object and saved.

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

Now all this above code does is updates the Property Member.Country.Code which is obviously not what I need it to do.

So from the docs, I figured I needed to create an override and got this:

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

My problem is during debugging, CountryLookup never gets called.

Possible reasons I can think of:

  • Nhibernate Proxy classes causing value injecter to not match the Country type? Tho this doesnt make sense because it works during the flattening.
  • Perhaps the unflattening isn't firing for some reason. I.e Dto is CountryCode and Domain is Country.Code

I need to use the CountryCode property on the Dto to call a countryService.LookupCode to return the correct object to use during the update injection.


Solution

  • Using the suggestion/reference from Omu this was the specific code to the problem.

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