AutoMapper 4.2 and Ninject 3.2

2019-03-25 05:58发布

问题:

I'm updating a project of mine to use AutoMapper 4.2, and I'm running into breaking changes. While I seem to have resolved said changes, I'm not entirely convinced I've done so in the most appropriate way.

In the old code, I have a NinjectConfiguration, and an AutoMapperConfiguration class that are each loaded by WebActivator. In the new version the AutoMapperConfiguration drops out and I instead instance a MapperConfiguration directly in the NinjectConfiguration class where the bindings are happening, like so:

private static void RegisterServices(
    IKernel kernel) {
    var profiles = AssemblyHelper.GetTypesInheriting<Profile>(Assembly.Load("???.Mappings")).Select(Activator.CreateInstance).Cast<Profile>();
    var config = new MapperConfiguration(
        c => {
            foreach (var profile in profiles) {
                c.AddProfile(profile);
            }
        });

    kernel.Bind<MapperConfiguration>().ToMethod(
        c =>
            config).InSingletonScope();

    kernel.Bind<IMapper>().ToMethod(
        c =>
            config.CreateMapper()).InRequestScope();

    RegisterModules(kernel);
}

So, is this the appropriate way of binding AutoMapper 4.2 using Ninject? It seems to be working so far, but I just want to make sure.

回答1:

In before IMapper interface didn't existed in the library so you had to implement interface and class below and bound them as a singleton pattern.

public interface IMapper
{
    T Map<T>(object objectToMap);
}

public class AutoMapperAdapter : IMapper
{
    public T Map<T>(object objectToMap)
    {
        //Mapper.Map is a static method of the library!
        return Mapper.Map<T>(objectToMap);
    }
}

Now you simply bind library's IMapper interface to single instance of mapperConfiguration.CreateMapper()

The Problem with your code tho, you should use a single instance(or as Ninject says, a constant) bind.

// A reminder
var config = new MapperConfiguration(
    c => {
        foreach (var profile in profiles) {
            c.AddProfile(profile);
        }
    });
// Solution starts here
var mapper = config.CreateMapper();
kernel.Bind<IMapper>().ToConstant(mapper);