AutoMapper官方文档(十四)【依赖注入】

来源:互联网 发布:淘宝上传视频要收费吗 编辑:程序博客网 时间:2024/06/07 01:45

AutoMapper支持使用静态服务定位构建自定义值解析器自定义类型转换器的能力:

Mapper.Initialize(cfg =>{    cfg.ConstructServicesUsing(ObjectFactory.GetInstance);    cfg.CreateMap<Source, Destination>();});

或动态服务定位,用于基于实例的容器(包括 子/嵌套 容器):

var mapper = new Mapper(Mapper.Configuration, childContainer.GetInstance);var dest = mapper.Map<Source, Destination>(new Source { Value = 15 });

一个意想不到或不直观的错误

使用DI与使用IQueryable.ProjectTo扩展方法有效地互斥。使用IEnumerable.Select(_mapper.Map<DestinationType>).ToList()来代替。

ASP.NET Core

有一个NuGet包与这里描述的默认注入机制一起使用。

Ninject注入框架

对于那些使用Ninject的人来说,这是一个用于AutoMapperNinject模块的例子

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;    }}

简单的注入器

工作流程如下:

     通过MyRegistrar.Register注册您的类型     MapperProvider允许您直接将IMapper的一个实例注入到其他类中     SomeProfile使用PropertyThatDependsOnIocValueResolver解析一个值     PropertyThatDependsOnIocValueResolver已经注入IService,然后可以使用

ValueResolver可以访问IService,因为我们通过MapperConfigurationExpression.ConstructServicesUsing注册我们的容器

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);    }}
原创粉丝点击