我有一个接口(interface) 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 中不起作用。我知道我可以指定 all Bar
和 Baz
但如果有 20 个,我不想管理它们,而是只需按照我上面创建 map 所做的操作即可。这可能吗?
最佳答案
我已经找到了解决这个问题的方法。我创建了一个 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;
}
}
}
这很棒,但需要将其注册到映射器注册表中。它需要位于列表的开头,因为我们想要捕获所有 int/IIdentific
源/目标组合(这放置在 Global.asax 等配置中):
var allMappers = MapperRegistry.AllMappers();
MapperRegistry.AllMappers = () => new IObjectMapper[]
{
new IdentifiableMapper(),
}.Concat(allMappers);
关于c# - AutoMapper 可以为接口(interface)创建映射,然后使用派生类型进行映射吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4534269/