您的位置:首页 > 移动开发

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

2017-11-28 16:57 417 查看
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
的人来说,这是一个用于
AutoMapper
Ninject
模块的例子

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: