[英]AutoMapper producing error when mapping from 2 sources to destination using customResolver
[英]C# Automapper How to resolve using property from customresolver
我正在使用以下映射將我的數據對象映射到viewmodel對象。
ObjectMapper.cs
public static class ObjectMapper
{
public static void Configure()
{
Mapper.CreateMap<User, UserViewModel>()
.ForMember(dest => dest.Title,
opt => opt.ResolveUsing<TitleValueResolver>())
.ForMember(dest => dest.Name,
opt => opt.ResolveUsing<NameValueResolver >())
.ForMember(dest => dest.ShortName,
opt => opt.ResolveUsing<ShortNameValueResolver >());
}
}
解析器
public class Parser{
public string GetTitle(string title){
/* add some logic */
return title;
}
public string GetName(string title){
/* add some logic */
return name;
}
public string GetShortName(string title){
/* add some logic */
return shortname;
}
}
AutoMapperCustomResolvers.cs
public class TitleValueResolver : ValueResolver<User, string>
{
private readonly BaseValueResolver _baseResolver;
public TitleValueResolver()
{
_baseResolver = new BaseValueResolver();
}
protected override string ResolveCore(Usersource)
{
return _baseResolver.Parser.GetTitle(source.TITLE);
}
}
public class NameValueResolver : ValueResolver<User, string>
{
private readonly BaseValueResolver _baseResolver;
public NameValueResolver()
{
_baseResolver = new BaseValueResolver();
}
protected override string ResolveCore(Usersource)
{
return _baseResolver.Parser.GetName(source.TITLE);
}
}
public class ShortNameValueResolver : ValueResolver<User, string>
{
private readonly BaseValueResolver _baseResolver;
public ShortNameValueResolver()
{
_baseResolver = new BaseValueResolver();
}
protected override string ResolveCore(Usersource)
{
return _baseResolver.Parser.GetShortName(source.TITLE);
}
}
我正在使用上面的代碼使用單獨的自定義值解析器將邏輯添加到目標屬性。 不確定這是正確的方法。
i)是否有更好的方法來實現這一目標?
ii)如果我想向自定義解析器構造函數注入一些依賴關系,又如何使用統一來解析?
謝謝
據我所知,您想利用ValueResolver
,它將多個源屬性解析為一個中間數據對象,該對象用於解析多個目標屬性。 作為示例,我假設以下源,目標,中間和解析器類型:
// source
class User
{
public string UserTitle { get; set; }
}
// target
class UserViewModel
{
public string VM_Title { get; set; }
public string VM_OtherValue { get; set; }
}
// intermediate from ValueResolver
class UserTitleParserResult
{
public string TransferTitle { get; set; }
}
class TypeValueResolver : ValueResolver<User, UserTitleParserResult>
{
protected override UserTitleParserResult ResolveCore(User source)
{
return new UserTitleParserResult { TransferTitle = source.UserTitle };
}
}
您需要一個目標屬性才能利用opt.ResolveUsing<TypeValueResolver>()
。 這意味着,您可以在適當的目標屬性可用的情況下建立映射。
因此,暫時將結果包裝到適當的容器類型中:
class Container<TType>
{
public TType Value { get; set; }
}
並創建一個映射
Mapper.CreateMap<User, Container<UserViewModel>>()
.ForMember(d => d.Value, c => c.ResolveUsing<TypeValueResolver>());
還有另一個映射
Mapper.CreateMap<UserTitleParserResult, UserViewModel>()
.ForMember(d => d.VM_Title, c => c.MapFrom(s => s.TransferTitle))
.ForMember(d => d.VM_OtherValue, c => c.Ignore());
還有另一個映射
Mapper.CreateMap<User, UserViewModel>()
.BeforeMap((s, d) =>
{
Mapper.Map<User, Container<UserViewModel>>(s, new Container<UserViewModel> { Value = d });
})
.ForAllMembers(c => c.Ignore());
// establish more rules for properties...
最后一個映射有點特殊,因為它依賴於嵌套映射,以便通過單獨配置的映射規則使用源中的值更新目標。 通過在實際映射類型的BeforeMap
中添加適當的中間映射和調用,可以為不同的屬性具有多個不同的傳輸映射。 由於AutoMapper不了解BeforeMap
的映射, BeforeMap
需要忽略其他映射中處理的屬性。
小用法示例:
var user = new User() { UserTitle = "User 1" };
// create by mapping
UserViewModel vm1 = Mapper.Map<UserViewModel>(user);
UserViewModel vm2 = new UserViewModel() { VM_Title = "Title 2", VM_OtherValue = "Value 2" };
// map source properties into existing target
Mapper.Map(user, vm2);
Dunno,如果這可以幫助您。 如果改寫問題來描述最初的問題,而不是懷疑是解決方案,那么可能會有更好的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.