Внедрение зависимостей AutoMapper с помощью Ninject

У меня возникли проблемы с вводом AutoMapper в приложение ASP.NET MVC 2 с использованием Ninject. В качестве руководства я использовал сообщение Джимми Богарда в Конфигурация типа AutoMapper и StructureMap.

public class AutoMapperModule : NinjectModule
{
    public override void Load()
    {
        Bind<ITypeMapFactory>().To<TypeMapFactory>();
        Bind<Configuration>().ToSelf().InSingletonScope().WithConstructorArgument("mapper", MapperRegistry.AllMappers);
        Bind<IConfiguration>().To<Configuration>();
        Bind<IConfigurationProvider>().To<Configuration>();
        Bind<IMappingEngine>().To<MappingEngine>();
    }
}

Ninject генерирует исключение при разрешении Configuration.

Ошибка активации IObjectMapper Нет соответствующих привязок, и тип не является самопереключаемым. Путь активации:
3) Инъекция зависимости IObjectMapper в параметрах-преобразователях конструктора типа Конфигурация

Обновление

Теперь это работает, используя следующую привязку:

    Bind<ITypeMapFactory>().To<TypeMapFactory>();
    Bind<Configuration>().ToConstant(new Configuration(Kernel.Get<ITypeMapFactory>(), MapperRegistry.AllMappers())).InSingletonScope();
    Bind<IConfiguration>().ToMethod(c => c.Kernel.Get<Configuration>());
    Bind<IConfigurationProvider>().ToMethod(c => c.Kernel.Get<Configuration>());
    Bind<IMappingEngine>().To<MappingEngine>();

Я опубликовал модуль на GitHub. AutoMapper.Ninject. Дополнительная информация в моем блоге: http://binaryspeakeasy.com/2010/09/automapper-ninject/

Ответ 1

Я получил его работу, но он не чувствует себя очень чистым, создавая экземпляр класса Configuration. Любые предложения по его очистке.

        Bind<ITypeMapFactory>().To<TypeMapFactory>();
        Bind<Configuration>().ToConstant(new Configuration(Kernel.Get<ITypeMapFactory>(), MapperRegistry.AllMappers())).InSingletonScope();
        Bind<IConfiguration>().ToMethod(c => c.Kernel.Get<Configuration>());
        Bind<IConfigurationProvider>().ToMethod(c => c.Kernel.Get<Configuration>());
        Bind<IMappingEngine>().To<MappingEngine>();

Ответ 2

Вы можете сделать это один лайнер, используя последнюю версию (в настоящее время 2.2.0).

kernel.Rebind<IMappingEngine>().ToMethod(context => Mapper.Engine);

В дополнение, я согласен с fodonnel, добавив фасад, чтобы скрыть интерфейс Automapper, это хорошая идея, однако я бы не взял подписи непосредственно из Automapper, если вам не нужны все эти функции.

Ответ 3

Также может быть хорошей идеей ввести фасад отображения. Вместо того, чтобы передавать IMappingEngine через свой код, создайте интерфейс IObjectMapper. Используемый интерфейс содержит сигнатуры методов, полученные непосредственно из кода автозапуска.

public interface IObjectMapper
{ 
  TDestination Map(TSource source);
  TDestination Map(TSource source, TDestination destination);
  object Map(object source, Type sourceType, Type destinationType);
  object Map(object source, object destination, Type sourceType, Type destinationType);
}

Ваша конфигурация по-прежнему будет зависеть от automapper.

Сообщение в блоге, которое я написал на нем, находится здесь: http://fodonnel.wordpress.com/2010/09/20/an-object-mapper-facade/