14.AutoMapper 之依賴注入(Dependency Injection)

https://www.jianshu.com/p/f66447282780

 

依賴注入(Dependency Injection)

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.ProjectToapp

ASP.NET Core

有一個NuGet包與這裏描述的默認注入機制搭配使用。ide

Ninject

對於那些使用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

  1. 經過 MyRegistrar.Register註冊你的類型
  2. MapperProvider容許你直接將IMapper的實例注入到其餘類中
  3. SomeProfile使用PropertyThatDependsOnIocValueResolver解析值
  4. PropertyThatDependsOnIocValueResolverIService注入其中

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

相關文章
相關標籤/搜索