我一直致力于将AutoMapper注入控制器。我喜欢Code Camp Server的实现。它创建了一个围绕AutoMapper的IMappingEngine的包装器。依赖注入使用StructureMap完成。但我需要使用Castle Windsor作为我的项目。那么,我们如何使用Windsor实现以下依赖注入和设置?我不是在寻找Castle Windsor中的逐行等效实现。如果你想这样做,请随意。相反,什么是Windsor相当于StructureMap的注册表和配置文件?我需要Profile来定义CreateMap<>如下。
感谢。
会议控制器:
public MeetingController(IMeetingMapper meetingMapper, ...)
会议映射器:
public class MeetingMapper : IMeetingMapper
{
private readonly IMappingEngine _mappingEngine;
public MeetingMapper(IMappingEngine mappingEngine)
{
_mappingEngine = mappingEngine;
}
public MeetingInput Map(Meeting model)
{
return _mappingEngine.Map<Meeting, MeetingInput>(model);
}
......
}
自动映射器注册表:
public class AutoMapperRegistry : Registry
{
public AutoMapperRegistry()
{
ForRequestedType<IMappingEngine>().TheDefault.Is.ConstructedBy(() => Mapper.Engine);
}
}
会议映射器配置文件:
public class MeetingMapperProfile : Profile
{
public static Func<Type, object> CreateDependencyCallback = (type) => Activator.CreateInstance(type);
public T CreateDependency<T>()
{
return (T)CreateDependencyCallback(typeof(T));
}
protected override void Configure()
{
Mapper.CreateMap<MeetingInput, Meeting>().ConstructUsing(
input => CreateDependency<IMeetingRepository>().GetById(input.Id) ?? new Meeting())
.ForMember(x => x.UserGroup, o => o.MapFrom(x => x.UserGroupId))
.ForMember(x => x.Address, o => o.Ignore())
.ForMember(x => x.City, o => o.Ignore())
.ForMember(x => x.Region, o => o.Ignore())
.ForMember(x => x.PostalCode, o => o.Ignore())
.ForMember(x => x.ChangeAuditInfo, o => o.Ignore());
}
}
答案 0 :(得分:3)
你的意思是如何在温莎注册?
你可能要注册FactorySupportFacility拳头......我现在无法检查。
container.AddFacility<FactorySupportFacility>();
然后
container.Register(Component.For<IMappingEngine>().UsingFactoryMethod(()=>
Mapper.Engine));
答案 1 :(得分:2)
我不熟悉Castle Windsor,但这里是StructureMap语法。您需要将注册表设置为略有不同。您不必将IMappingEngine设置为Mapper.Engine,而是需要配置更多接口。这是一个更多的工作,但这将允许您将配置文件设置为注册的一部分。
public AutoMapperRegistry()
{
//type mapping
For<ConfigurationStore>()
.Singleton()
.Use(ctx =>
{
ITypeMapFactory factory = ctx.GetInstance<ITypeMapFactory>();
ConfigurationStore store
= new ConfigurationStore(factory, MapperRegistry.AllMappers());
IConfiguration cfg = store;
//Here's where you load your profile
cfg.AddProfile<MeetingMapperProfile>();
store.AssertConfigurationIsValid();
return store;
});
For<IConfigurationProvider>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IConfiguration>().Use(ctx => ctx.GetInstance<ConfigurationStore>());
For<IMappingEngine>().Use<MappingEngine>();
For<ITypeMapFactory>().Use<TypeMapFactory>();
}
答案 2 :(得分:2)
我意识到这有点旧,但我使用Castle Windsor,使用安装程序加载AutoMapper配置文件相当容易:
using System.Linq;
using System.Reflection;
using AutoMapper;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace YourNamespace
{
public class AutoMapperInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
Mapper.Initialize(m => m.ConstructServicesUsing(container.Resolve));
container.Register(Types.FromAssembly(Assembly.GetExecutingAssembly()).BasedOn<IValueResolver>());
container.Register(Types.FromThisAssembly().BasedOn<Profile>().WithServiceBase());
var profiles = container.ResolveAll<Profile>();
profiles.ToList().ForEach(p => Mapper.AddProfile(p));
container.Register(Component.For<IMappingEngine>().Instance(Mapper.Engine));
}
}
}
此安装程序会选择问题中显示的MeetingMapperProfile
,或基于AutoMapper Profile
的任何其他类。