我正在使用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永远不会被调用。
我能想到的可能原因:
我需要使用Dto上的CountryCode属性来调用countryService.LookupCode以返回在更新注入期间使用的正确对象。
答案 0 :(得分:3)
entity.Country.Code <- dto.CountryCode
你需要的是:
entity.Country <- dto.CountryCode
所以你的解决方案就是继承一个ExactValueInjection,你可以从CountryCode转到Country。
我建议您这样做与我在我的另一个项目的现场演示中所做的相同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吗?到国家/地区然后返回以及继承实体
的任何其他类型答案 1 :(得分: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;
}
答案 2 :(得分:0)
框架是否调用了setter方法?在大多数DI框架中,标准是setMethod()中的小写's'。只是第一个想法的推荐。