Как использовать AutoMapper с Ninject.Сеть.В MVC?
настройка
у меня есть AutoMapperConfiguration статический класс, который устанавливает сопоставления AutoMapper:
static class AutoMapperConfiguration()
{
internal static void SetupMappings()
{
Mapper.CreateMap<long, Category>.ConvertUsing<IdToEntityConverter<Category>>();
}
}
здесь IdToEntityConverter<T> обычай ITypeConverter это выглядит так:
class IdToEntityConverter<T> : ITypeConverter<long, T> where T : Entity
{
private readonly IRepository _repo;
public IdToEntityConverter(IRepository repo)
{
_repo = repo;
}
public T Convert(ResolutionContext context)
{
return _repo.GetSingle<T>(context.SourceValue);
}
}
IdToEntityConverter принимает IRepository в своем конструкторе, чтобы преобразовать идентификатор обратно в фактический объект, нажав на базу данных. Обратите внимание, что у него нет конструктора по умолчанию.
в моем ASP.NET s Global.asax, это то, что у меня есть для OnApplicationStarted() и CreateKernel():
protected override void OnApplicationStarted()
{
// stuff that's required by MVC
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
// our setup stuff
AutoMapperConfiguration.SetupMappings();
}
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<IRepository>().To<NHibRepository>();
return kernel;
}
так OnApplicationCreated() будем называть AutoMapperConfiguration.SetupMappings() настройки отображения и CreateKernel() свяжет экземпляр NHibRepository до .
всякий раз, когда я запускаю этот код и пытаюсь заставить AutoMapper преобразовать идентификатор категории обратно в объект категории, я получаю AutoMapperMappingException это говорит, что конструктор по умолчанию не существует на IdToEntityConverter.
попытки
добавлен конструктор по умолчанию
IdToEntityConverter. Теперь я получаюNullReferenceException, что указывает на то, что инъекция не работает.сделал отдельный
_repoполе в публичное свойство и добавил . Все еще получаюNullReferenceException.добавил
[Inject]атрибут конструктора, который принимаетIRepository. Все еще получаюNullReferenceException.-
думая, что, возможно, Ninject не может перехватить
AutoMapperConfiguration.SetupMappings()вызов вOnApplicationStarted(), я переехал это к чему-то, что я знаю, впрыскивает правильно, один из моих контроллеров, например:public class RepositoryController : Controller { static RepositoryController() { AutoMapperConfiguration.SetupMappings(); } }все еще получаю
NullReferenceException.
вопрос
мой вопрос в том, как заставить Ninject ввести IRepository на IdToEntityConverter?
2 ответов
вы должны предоставить AutoMapper доступ к контейнеру DI. Мы используем StructureMap, но я думаю, что ниже должно работать с любым DI.
мы используем это (в одной из наших задач загрузчика)...
private IContainer _container; //Structuremap container
Mapper.Initialize(map =>
{
map.ConstructServicesUsing(_container.GetInstance);
map.AddProfile<MyMapperProfile>();
}
ответ@ozczecho является точечным, но я публикую версию Ninject кода, потому что у него есть одно небольшое предостережение, которое поймало нас на некоторое время:
IKernel kernel = null; // Make sure your kernel is initialized here
Mapper.Initialize(map =>
{
map.ConstructServicesUsing(t => kernel.Get(t));
});
вы не можете просто пройти в kernel.Get to map.ConstructServicesUsing потому что этот способ имеет params параметр в дополнение к типу. Но поскольку параметры являются необязательными, вы можете просто создать лямбда-выражение, чтобы создать анонимную функцию, чтобы получить то, что вам нужно.