Как использовать 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
параметр в дополнение к типу. Но поскольку параметры являются необязательными, вы можете просто создать лямбда-выражение, чтобы создать анонимную функцию, чтобы получить то, что вам нужно.