我让 AutoMapper 和 Windsor 与 Profiles 和 TypeConverters 配合得很好。我认为这对你来说应该足够不可知了,因为 AutoMapper 会自动选择 ITypeConverter 的任何实现。
如果它解决了你的问题,请告诉我。
首先我在 Windsor 注册了 AutoMapper:
public class AutoMapperInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
// Replace by whatever assembly contains your ITypeConverter, IValueResolver and Profile implementations
var myAssembly = Classes.FromAssemblyNamed("MyAssembly");
// Register AutoMapper such that it uses a singleton configuration
container.Register(
myAssembly.BasedOn(typeof(ITypeConverter<,>)).WithServiceSelf(),
myAssembly.BasedOn<IValueResolver>().WithServiceBase(),
myAssembly.BasedOn<Profile>().WithServiceBase(),
Component.For<IEnumerable<IObjectMapper>>().UsingFactoryMethod(() => MapperRegistry.Mappers),
Component.For<ConfigurationStore>()
.LifestyleSingleton()
.UsingFactoryMethod(x =>
{
var typeMapFactory = x.Resolve<ITypeMapFactory>();
var mappers = x.Resolve<IEnumerable<IObjectMapper>>();
ConfigurationStore configurationStore = new ConfigurationStore(typeMapFactory, mappers);
configurationStore.ConstructServicesUsing(x.Resolve);
configurationStore.AssertConfigurationIsValid();
return configurationStore;
}),
Component.For<IConfigurationProvider>().UsingFactoryMethod(x => x.Resolve<ConfigurationStore>()),
Component.For<IConfiguration>().UsingFactoryMethod(x => x.Resolve<ConfigurationStore>()),
Component.For<IMappingEngine>().ImplementedBy<MappingEngine>().LifestyleSingleton(),
Component.For<ITypeMapFactory>().ImplementedBy<TypeMapFactory>()
);
// Add all Profiles
var configuration = container.Resolve<IConfiguration>();
container.ResolveAll<Profile>().ToList().ForEach(configuration.AddProfile);
}
}
然后我创建了一个配置文件,在其中我使用一点反射注册了所有 ITypeConverter 实现:
public class TypeConverterProfile : Profile
{
private readonly IConfiguration _configuration;
public TypeConverterProfile(IConfiguration configuration)
{
_configuration = configuration;
}
protected override void Configure()
{
// Replace by whatever assembly contains your ITypeConverter implementations
var myAssembly = Classes.FromAssemblyNamed("MyAssembly");
var typeConverters =
from x in myAssembly.GetTypes()
from type in x.GetInterfaces()
where type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ITypeConverter<,>)
select new
{
Type = x,
Source = type.GetGenericArguments()[0],
Destination = type.GetGenericArguments()[1]
};
// Apply type converters to AutoMapper configuration
foreach (var typeConverter in typeConverters)
_configuration.CreateMap(typeConverter.Source, typeConverter.Destination).ConvertUsing(typeConverter.Type);
}
}
AutoMapper 现在将自动拾取并使用“MyAssembly”中的任何 Profiles 和 ITypeConverters 实现。
例如,您可能有一个个人资料:
public class MapProfile : Profile
{
private readonly IConfiguration _configuration;
public MapProfile(IConfiguration configuration)
{
_configuration = configuration;
}
protected override void Configure()
{
// Create an auto-map from SearchResultModel -> SearchResult
_configuration.CreateMap<SearchResultModel, SearchResult>();
}
}
还有一个 ITypeConverter:
public class SearchRequestConverter : ITypeConverter<SearchRequest, SearchRequestModel>
{
private readonly IConfiguration _configuration;
public MapProfile(IConfiguration configuration)
{
// Also in the ITypeConverter you may have the IConfiguration injected in case you need it
_configuration = configuration;
}
public SearchRequestModel Convert(ResolutionContext context)
{
var model = (SearchRequest) context.SourceValue;
return new SearchRequestModel
{
Results = model.Results
};
}
}
最后,您通过依赖 IMappingEngine 在您的类中执行实际映射:
public class FolderRepository
{
private readonly IMappingEngine _mappingEngine;
public FolderRepository(IMappingEngine mappingEngine)
{
_mappingEngine = mappingEngine;
}
public SearchResult Search(SearchRequest searchRequest)
{
// This mapping will use the ITypeConverter implementation
SearchRequestModel searchRequestModel = _mappingEngine.Map<SearchRequestModel>(searchRequest);
SearchResultModel searchResultModel = Search(searchRequestModel);
// This mapping will use the auto-map from the Profile
SearchResult searchResult = _mappingEngine.Map<SearchResultModel>(searchResultModel);
return searchResult;
}
private SearchResultModel Search(SearchRequestModel searchRequestModel)
{
SearchResultModel result = new SearchResultModel();
// ... perform search ...
return result;
}
}
要拥有更多 ITypeConverter,您只需实现它们,Windsor 和 AutoMapper 就会自动获取它们。可以在配置文件中添加手动自动地图 (CreateMap)。
这能解决你的问题吗?