我有一个接口IFoo:
public interface IFoo
{
int Id { get; set; }
}
然后是一个具体的实现:
public class Bar : IFoo
{
public int Id { get; set; }
public string A { get; set; }
}
public class Baz : IFoo
{
public int Id { get; set; }
public string B { get; set; }
}
我希望能够映射所有 IFoo
,但要指定其派生类型:
Mapper.CreateMap<int, IFoo>().AfterMap((id, foo) => foo.Id = id);
然后映射(没有明确地为Bar和Baz创建地图):
var bar = Mapper.Map<int, Bar>(123);
// bar.Id == 123
var baz = Mapper.Map<int, Baz>(456);
// baz.Id == 456
但这在1.1中不起作用。我知道我可以指定所有 Bar
和Baz
但是如果有20个这样的话,我不想管理它们而只是拥有我上面所做的用于创建地图。这可能吗?
答案 0 :(得分:2)
我找到了解决这个问题的方法。我创建了IObjectMapper
:
// In this code IIdentifiable would be the same as IFoo in the original post.
public class IdentifiableMapper : IObjectMapper
{
public bool IsMatch(ResolutionContext context)
{
var intType = typeof(int);
var identifiableType = typeof(IIdentifiable);
// Either the source is an int and the destination is an identifiable.
// Or the source is an identifiable and the destination is an int.
var result = (identifiableType.IsAssignableFrom(context.DestinationType) && intType == context.SourceType) || (identifiableType.IsAssignableFrom(context.SourceType) && intType == context.DestinationType);
return result;
}
public object Map(ResolutionContext context, IMappingEngineRunner mapper)
{
// If source is int, create an identifiable for the destination.
// Otherwise, get the Id of the identifiable.
if (typeof(int) == context.SourceType)
{
var identifiable = (IIdentifiable)mapper.CreateObject(context);
identifiable.Id = (int)context.SourceValue;
return identifiable;
}
else
{
return ((IIdentifiable)context.SourceValue).Id;
}
}
}
这很棒,但需要注册到mapper注册表。它需要位于列表的开头,因为我们想要捕获所有int/IIdentifiable
源/目标组合(这被放置在诸如Global.asax之类的配置中):
var allMappers = MapperRegistry.AllMappers();
MapperRegistry.AllMappers = () => new IObjectMapper[]
{
new IdentifiableMapper(),
}.Concat(allMappers);