使用 NInject 注入 automapper 映射器
Inject autommaper mapper using NInject
我想使用 NInject.
将 AutoMapper.IMapper
单个实例作为 singleton
注入
实际上,我 un/mapping from/to 个对象使用 AutoMapper static API. It's turned out obsolete and I'm looking forward to taking advantage of the ocassion to inject it using NInject。
目前,我正在使用此代码来创建我的 IMapper
实例:
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.DigitalResourceProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.DigitalInputProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.FollowUpActivityProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.ResourceProfile());
如您所见,我还有一些配置文件要初始化。
我应该如何构建所有这些?
到目前为止,我只能创建一个 Module
但我不知道如何进行绑定。
public class AutoMapperModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<AutoMapper.MapperConfiguration>().ToProvider<AutoMapperconfigurationProvider>().InSingletonScope();
this.Bind<AutoMapper.IMapper>().To<AutoMapper.Mapper>();
}
private class AutoMapperconfigurationProvider : IProvider<AutoMapper.MapperConfiguration>
{
public object Create(IContext context)
{
AutoMapper.MapperConfiguration instance = new AutoMapper.MapperConfiguration(
cfg =>
{
cfg.AddProfile(new UI.Mappings.Profiles.DigitalResourceProfile());
cfg.AddProfile(new UI.Mappings.Profiles.DigitalInputProfile());
cfg.AddProfile(new UI.Mappings.Profiles.FollowUpActivityProfile());
cfg.AddProfile(new UI.Mappings.Profiles.ResourceProfile());
}
);
return instance;
}
public Type Type
{
get { throw new NotImplementedException(); }
}
}
}
每次需要IMapper
映射对象的时候我都想写这句话:
IMapper mapper = kernel.Get<IMapper>();
有什么想法吗?
我调查过这个。
我发现了以下内容:
在文档中我们可以发现我们可以这样做:
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<SomeProfile>();
cfg.CreateMap<Source, Dest>();
});
var mapper = config.CreateMapper(); // option 1
// or
var mapper = new Mapper(config); // option 2
您的代码可以使用 option 2
,因为您绑定了 configuration
和 mapper
。
但是这里我们有两个问题。
1) 您需要将第一个绑定更改为将 MapperConfiguration
绑定为接口 IConfigurationProvider
,因为 Mapper
的构造函数需要它:
public Mapper(IConfigurationProvider configurationProvider)
: this(configurationProvider, configurationProvider.ServiceCtor)
{
}
但是这里我们遇到了第二个问题。
2) 在 automapper 版本 4.2.1 中(我相信你是从 NuGet 下载的)Mapper
class 只有 internal
构造函数。它在文档中有一个 public 构造函数(这很奇怪),我认为在未来的版本中会有。
因此,现在您需要修改 Load
方法以使用 option 1
:
public override void Load()
{
this.Bind<AutoMapper.MapperConfiguration>().ToProvider<AutoMapperconfigurationProvider>().InSingletonScope();
this.Bind<AutoMapper.IMapper>().ToMethod(context => context.Kernel.Get<MapperConfiguration>().CreateMapper());
}
然后你可以调用IMapper mapper = kernel.Get<IMapper>();
获取映射器实例。
它将使用 public IMapper CreateMapper() => new Mapper(this);
并将创建 IMapper 的实例。注意:调用CreateMapper
方法需要使用MapperConfiguration(不是IConfiguration provider),与Mapper
.
的public/internal构造函数情况相同
这应该有所帮助。
我想使用 NInject.
将AutoMapper.IMapper
单个实例作为 singleton
注入
实际上,我 un/mapping from/to 个对象使用 AutoMapper static API. It's turned out obsolete and I'm looking forward to taking advantage of the ocassion to inject it using NInject。
目前,我正在使用此代码来创建我的 IMapper
实例:
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.DigitalResourceProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.DigitalInputProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.FollowUpActivityProfile());
AutoMapper.Mapper.AddProfile(new UI.Mappings.Profiles.ResourceProfile());
如您所见,我还有一些配置文件要初始化。
我应该如何构建所有这些?
到目前为止,我只能创建一个 Module
但我不知道如何进行绑定。
public class AutoMapperModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<AutoMapper.MapperConfiguration>().ToProvider<AutoMapperconfigurationProvider>().InSingletonScope();
this.Bind<AutoMapper.IMapper>().To<AutoMapper.Mapper>();
}
private class AutoMapperconfigurationProvider : IProvider<AutoMapper.MapperConfiguration>
{
public object Create(IContext context)
{
AutoMapper.MapperConfiguration instance = new AutoMapper.MapperConfiguration(
cfg =>
{
cfg.AddProfile(new UI.Mappings.Profiles.DigitalResourceProfile());
cfg.AddProfile(new UI.Mappings.Profiles.DigitalInputProfile());
cfg.AddProfile(new UI.Mappings.Profiles.FollowUpActivityProfile());
cfg.AddProfile(new UI.Mappings.Profiles.ResourceProfile());
}
);
return instance;
}
public Type Type
{
get { throw new NotImplementedException(); }
}
}
}
每次需要IMapper
映射对象的时候我都想写这句话:
IMapper mapper = kernel.Get<IMapper>();
有什么想法吗?
我调查过这个。
我发现了以下内容:
在文档中我们可以发现我们可以这样做:
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<SomeProfile>();
cfg.CreateMap<Source, Dest>();
});
var mapper = config.CreateMapper(); // option 1
// or
var mapper = new Mapper(config); // option 2
您的代码可以使用 option 2
,因为您绑定了 configuration
和 mapper
。
但是这里我们有两个问题。
1) 您需要将第一个绑定更改为将 MapperConfiguration
绑定为接口 IConfigurationProvider
,因为 Mapper
的构造函数需要它:
public Mapper(IConfigurationProvider configurationProvider)
: this(configurationProvider, configurationProvider.ServiceCtor)
{
}
但是这里我们遇到了第二个问题。
2) 在 automapper 版本 4.2.1 中(我相信你是从 NuGet 下载的)Mapper
class 只有 internal
构造函数。它在文档中有一个 public 构造函数(这很奇怪),我认为在未来的版本中会有。
因此,现在您需要修改 Load
方法以使用 option 1
:
public override void Load()
{
this.Bind<AutoMapper.MapperConfiguration>().ToProvider<AutoMapperconfigurationProvider>().InSingletonScope();
this.Bind<AutoMapper.IMapper>().ToMethod(context => context.Kernel.Get<MapperConfiguration>().CreateMapper());
}
然后你可以调用IMapper mapper = kernel.Get<IMapper>();
获取映射器实例。
它将使用 public IMapper CreateMapper() => new Mapper(this);
并将创建 IMapper 的实例。注意:调用CreateMapper
方法需要使用MapperConfiguration(不是IConfiguration provider),与Mapper
.
这应该有所帮助。