AutoMapper
支持使用靜態服務定位構建自定義值解析器和自定義類型轉換器的功能:javascript
Mapper.Initialize(cfg => { cfg.ConstructServicesUsing(ObjectFactory.GetInstance); cfg.CreateMap<Source, Destination>(); });
或者在基於實例的容器(包括子/嵌套容器)中使用動態服務定位:java
var mapper = new Mapper(Mapper.Configuration, childContainer.GetInstance); var dest = mapper.Map<Source, Destination>(new Source { Value = 15 });
使用IQueryable.ProjectTo
擴展方法與使用依賴注入是互斥的。請使用IEnumerable.Select(_mapper.Map<DestinationType>).ToList()
來代替IQueryable.ProjectTo
。app
有一個NuGet包與這裏描述的默認注入機制搭配使用。ide
對於那些使用Ninject
的人來講,這有一個AutoMapper
使用的Ninject
模塊的例子ui
public class AutoMapperModule : NinjectModule { public override void Load() { Bind<IValueResolver<SourceEntity, DestModel, bool>>().To<MyResolver>(); var mapperConfiguration = CreateConfiguration(); Bind<MapperConfiguration>().ToConstant(mapperConfiguration).InSingletonScope(); // This teaches Ninject how to create automapper instances say if for instance // MyResolver has a constructor with a parameter that needs to be injected Bind<IMapper>().ToMethod(ctx => new Mapper(mapperConfiguration, type => ctx.Kernel.Get(type))); } private MapperConfiguration CreateConfiguration() { var config = new MapperConfiguration(cfg => { // Add all profiles in current assembly cfg.AddProfiles(GetType().Assembly); }); return config; } }
工做流程以下:spa
MyRegistrar.Register
註冊你的類型MapperProvider
容許你直接將IMapper
的實例注入到其餘類中SomeProfile
使用PropertyThatDependsOnIocValueResolver
解析值PropertyThatDependsOnIocValueResolver
將IService
注入其中ValueResolver
能訪問IService
,是由於咱們經過MapperConfigurationExpression.ConstructServicesUsing
註冊容器。code
public class MyRegistrar { public void Register(Container container) { // Injectable service container.RegisterSingleton<IService, SomeService>(); // Automapper container.RegisterSingleton(() => GetMapper(container)); } private AutoMapper.IMapper GetMapper(Container container) { var mp = container.GetInstance<MapperProvider>(); return mp.GetMapper(); } } public class MapperProvider { private readonly Container _container; public MapperProvider(Container container) { _container = container; } public IMapper GetMapper() { var mce = new MapperConfigurationExpression(); mce.ConstructServicesUsing(_container.GetInstance); var profiles = typeof(SomeProfile).Assembly.GetTypes() .Where(t => typeof(Profile).IsAssignableFrom(t)) .ToList(); mce.AddProfiles(profiles); var mc = new MapperConfiguration(mce); mc.AssertConfigurationIsValid(); IMapper m = new Mapper(mc, t => _container.GetInstance(t)); return m; } } public class SomeProfile : Profile { public SomeProfile() { var map = CreateMap<MySourceType, MyDestinationType>(); map.ForMember(d => d.PropertyThatDependsOnIoc, opt => opt.ResolveUsing<PropertyThatDependsOnIocValueResolver>()); } } public class PropertyThatDependsOnIocValueResolver : IValueResolver<MySourceType, object, int> { private readonly IService _service; public PropertyThatDependsOnIocValueResolver(IService service) { _service = service; } int IValueResolver<MySourceType, object, int>.Resolve(MySourceType source, object destination, int destMember, ResolutionContext context) { return _service.MyMethod(source); } }
碼字不易,動動手指給個贊吧ip