要获得DI框架以将依赖项注入到Automapper自定义TypeConverter中,通常使用MapperConfiguration对象的ConstructServicesUsing方法。因此,使用ASP.NET核心DI,我希望能够像这样配置AutoMapper:
public static IMapperConfiguration Configure(IServiceProvider provider)
{
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<MyProfile>();
cfg.ConstructServicesUsing(type => provider.GetService(type));
});
config.AssertConfigurationIsValid();
return config;
}MapperConfiguration对象将被配置为startup.cs中的可注入服务,因此:
public void ConfigureServices(IServiceCollection services)
{
//other service configuration omitted for simplicity
//Automapper config
var provider = services.BuildServiceProvider();
var config = AutoMapperConfig.Configure(provider);
services.AddInstance(config);
}并且依赖项(在本例中是Automapper本身)将被注入到TypeConverter构造函数中,如下所示。
public class MyConverter : ITypeConverter<ThisType, ThatType>
{
private IMapper _mapper;
public MyConverter(IMapperConfiguration mapperConfig)
{
var mc = mapperConfig as MapperConfiguration;
_mapper = mc.CreateMapper();
}
public ThatType Convert(ResolutionContext context)
{
//do something with _mapper here
}
}我在几个DI框架中成功地使用了这个模式,但是我无法让它与ASP.NET核心一起工作。据猜测,我认为可能需要给Automapper一个真正的IServiceProvider实例,这个实例是在.NET方法完成后由ConfigureServices构建的。但是,即使我将配置的这一部分推迟到配置方法(参见下面),依赖项仍然不会被注入到TypeConverter中。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider provider)
{
var config = provider.GetService<IMapperConfiguration>();
config.ConstructServicesUsing(type => provider.GetService(type));
}因此,我的问题是:如何使用ASP.NET核心配置Automapper,以便将依赖项注入自定义TypeConverters?
发布于 2016-05-18 10:28:40
我发现解决这个问题的方法在于正确配置ConstructServicesUsing工厂方法。正如@ the所指出的,使用IServiceCollection.AddSingleton方法可以在Startup.cs的ConfigureServices方法中配置Automapper,这是应该这样做的:
public void ConfigureServices(IServiceCollection services)
{
//other service configuration omitted for simplicity
//Automapper config
services.AddSingleton(provider => AutoMapperConfig.Configure(provider));
}但至关重要的是,Automapper必须配置为使用.NET Core的ActivatorUtilities类来创建服务实例(归功于这篇文章给了我这个想法):
public static IMapperConfiguration Configure(IServiceProvider provider)
{
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<MyProfile>();
cfg.ConstructServicesUsing(type => ActivatorUtilities.CreateInstance(provider, type));
});
config.AssertConfigurationIsValid();
return config;
}使用这种方法,Automapper被配置为将任何服务依赖项注入自定义TypeConverters和ValueResolvers。只需确保任何这样的服务也会添加到IServiceCollection实例中的ConfigureServices中。
发布于 2016-05-17 21:47:01
您可以/应该使用工厂方法注入/实例化服务。
services.AddSingleton<IMapperConfiguration>( (serviceProvider) => AutoMapperConfig.Configure(serviceProvider) );这样,您就可以将对Configure的调用推迟到第一次解决IMapperConfiguration时。因为它是单例的,所以对于应用程序容器的其余部分,它将保持活动状态,对RequestService的进一步调用将返回相同的实例。
编辑:
尝试从config.AssertConfigurationIsValid();方法中删除AutoMapperConfig.Configure并在Startup.cs中添加以下代码
public void Configure(IServiceProvider app)
{
app.VerifyAutoMapperConfig();
}AutoMapperConfigExtensions.cs
// So one doesn't have to add namespaces to become available
// inside Startup.cs; Recommended way all middleware register their
// AddXxx and UseXxx extension methods
namespace Microsoft.Extensions.DependencyInjection {
public static class AutoMapperConfigExtensions
{
public static void VerifyAutoMapperConfig(this IServiceProvider app)
{
var config = app.RequestService<IMapperConfiguration>();
config.AssertConfigurationIsValid();
}
}
}https://stackoverflow.com/questions/37283139
复制相似问题