Inject autommaper mapper using NInject

I want to inject a AutoMapper.IMapper single instance as a singleton using NInject.

Actually, I'm un/mapping from/to objects using the AutoMapper static API. It's turned out obsolete and I'm looking forward to taking advantage of the ocassion to inject it using NInject.

Currently, I'm using this code in order to create my IMapper instance:

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());

As you can see, I've some profiles to initialize as well.

How should I build all that?

Until now, I've only been able to create a Module but I don't know how to make the bindings up.

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

I'd like to write this sentence each time I need a IMapper to map objects:

IMapper mapper = kernel.Get<IMapper>();

Any ideas?


I investigated this.

And I found the following:

In documentation we can found that we can do something like:

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

Your code would work with using the option 2 , because you have binding for configuration and for mapper .

But here we have two problems. 1) You need to change your first binding to bind MapperConfiguration as an interface IConfigurationProvider because the constructor of Mapper needs it:

public Mapper(IConfigurationProvider configurationProvider)
    : this(configurationProvider, configurationProvider.ServiceCtor)
{
}

But here we got the second problem.

2) In automapper version 4.2.1 (as I believe you downloaded from NuGet) the Mapper class has only internal constructors. It has a public constructors in documentation (which is weird) and I think will have in a future release.

Therefore, for now you need to modify Load method to use option 1 :

public override void Load()
{
    this.Bind<AutoMapper.MapperConfiguration>().ToProvider<AutoMapperconfigurationProvider>().InSingletonScope();
    this.Bind<AutoMapper.IMapper>().ToMethod(context => context.Kernel.Get<MapperConfiguration>().CreateMapper());
}

And then you can call IMapper mapper = kernel.Get<IMapper>(); to get the mapper instance.

It will use public IMapper CreateMapper() => new Mapper(this); and will create the instance of IMapper. Note: you need to use MapperConfiguration (not IConfiguration provider) to call CreateMapper method, it has the same situation as with public/internal constructors of Mapper .

That should help.

链接地址: http://www.djcxy.com/p/74402.html

上一篇: 单元测试,依赖注入和AutoMapper注释

下一篇: 使用NInject注入自动缩放器映射器