我有AutoMapper
个配置文件,目前依赖UrlHelper
进行以下映射:
CreateMap<Post, OpenGraphModel>().ForMember(
m => m.Title,
x => x.MapFrom(p => p.Link.Title)
).ForMember(
m => m.Description,
x => x.MapFrom(p => p.Link.Description)
).ForMember(
m => m.Image,
x => x.MapFrom(p => p.Link.Picture)
).ForMember(
m => m.Url,
x => x.MapFrom(p => urlHelper.RouteUrl("PostShortcut", new { id = p.Id }, "http"))
);
直到我想在Web请求之外的上下文中重用我的AutoMapper
个人资料时,这一点很好。
我可以为此考虑三种解决方案,其中没有一种真正让我信服(没有特别的顺序):
从映射配置文件中完全删除UrlHelper
依赖项。
这意味着我现在必须手动映射Url
OpenGraphModel
的{{1}}属性,在我看来,这种方式违背了使用AutoMapper
的目的。我喜欢我的映射器能够在目标对象中设置我需要的所有属性。
从非Web上下文中删除此映射配置文件,因为非Web请求上下文不应直接映射到视图模型。
为了实现这一点,我必须使我的IMapper
实例成为瞬态,每个Web请求(或线程),而不是单例,这会引入我不想介绍的额外开销。
第三种选择是不在非Web请求上下文(即作业)上使用IMapper
实现,但这似乎是不可能的,因为我重用了最终的组件要求我使用映射器。
我想两个单独的地图制作者会使最有意义的(根据上下文选择个人资料),但我不知道应该怎么做这样做,这是我的AutoMapper安装程序的当前形式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using AutoMapper;
using AutoMapper.Mappers;
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace Common
{
internal sealed class AutoMapperInstaller : IWindsorInstaller
{
private readonly Type[] profileTypes;
public AutoMapperInstaller(params Type[] profileTypes)
{
if (profileTypes == null)
{
throw new ArgumentNullException("profileTypes");
}
this.profileTypes = profileTypes;
}
public void Install(IWindsorContainer container, IConfigurationStore store)
{
IEnumerable<Assembly> assemblies = profileTypes.Select(t => t.Assembly).ToList();
foreach (Assembly assembly in assemblies)
{
container.Register(
AllTypes
.FromAssembly(assembly)
.BasedOn(typeof (ITypeConverter<,>))
.WithServiceSelf()
);
}
foreach (Assembly assembly in assemblies)
{
container.Register(
Classes
.FromAssembly(assembly)
.BasedOn<Profile>()
.LifestyleTransient()
);
}
container.Register(
Component
.For<ITypeMapFactory>()
.ImplementedBy<TypeMapFactory>()
.LifestyleTransient()
);
container.Register(
Component
.For<IConfiguration, IConfigurationProvider>()
.UsingFactoryMethod(InstanceConfigurationStore)
.LifestyleTransient()
);
container.Register(
Component
.For<IMappingEngine>()
.ImplementedBy<MappingEngine>()
.LifestyleTransient()
);
container.Register(
Component
.For<IMapper>()
.ImplementedBy<Mapper>()
.DynamicParameters(
(k, parameters) => parameters["profileTypes"] = profileTypes
)
.LifestyleSingleton()
);
}
private ConfigurationStore InstanceConfigurationStore(IKernel kernel)
{
ITypeMapFactory typeMapFactory = kernel.Resolve<ITypeMapFactory>();
IEnumerable<IObjectMapper> mappers = MapperRegistry.AllMappers();
return new ConfigurationStore(typeMapFactory, mappers);
}
}
}
答案 0 :(得分:1)
通过模拟在非Web请求上下文中传递给RequestContext
的{{1}}来解决。