4

I've been trying to setup AutoMapper to instantiate all objects via Ninject. I've got the following code in my global.asax file

Mapper.Configuration.ConstructServicesUsing(x => kernel.Get(x));

And as an example I have the following mapping

Mapper.CreateMap<TestModel, IndexViewModel>();

However, this does not appear to be working. I get an error that 'IndexViewModel' does not have a default constructor.

I can get the mapper to work by explicitly telling automapper to use ninject in the mapping.

Mapper.CreateMap<TestModel, IndexViewModel>().ConstructUsingServiceLocator();

However, I'd rather not have to do this for every single mapping. Am I missing something?

William
  • 8,007
  • 5
  • 39
  • 43
  • You haven't supplied IndexViewModel source; does it have a default constructor? – Peter Ritchie May 11 '12 at 21:58
  • @Peter No it doesn't have a default constructor. If I add one AutoMapper will create the IndexViewModel no problem, however it will not use Ninject to do so. – William May 11 '12 at 22:04
  • 5
    Why does your view models not have default constructors? Why do you need them to be managed by Ninject? View models without default constructors will cause you lots of headaches. What about POST controller actions that take those view models as action arguments? You will have to write custom model binders for them. Seems complex. – Darin Dimitrov May 12 '12 at 09:59
  • @Darin fair point. It was really just an exercise to have all object construction in my application go via the container. I quite liked the idea of mapping models from ID's like this - http://stackoverflow.com/questions/4074609/how-do-i-use-automapper-with-ninject-web-mvc – William May 15 '12 at 08:02
  • @Darin: a custom modelbinder which uses di to create the viewmodel classes is not that complex. I use that approach to set some common base properties in every viewmodel (baseclass). – Jan May 22 '12 at 07:51
  • Have you registered your `IndexViewModel` with Ninject? Can you resolve it with an explicit `kernel.Get()` call? – Damian Powell Jun 09 '12 at 19:50
  • 3
    On another matter, i *strongly* recommend putting all you mapper configurations into AutoMapper profiles. Then during your bootstrap phase, find all the profiles and register them with AM, then call `Mapper.AssertConfigurationIsValid()`. I had *lost* of pain in a project with conflicting mappings recently, until we adopted this pattern. – Damian Powell Jun 09 '12 at 19:51
  • Are you using the Ninject MVC3 dependency resolver? If you created your own dependency resolver inheriting from `IDependencyResolver` that knew how to create these view models, I think that would achieve your goal. – neontapir Oct 16 '12 at 22:49
  • @DamianPowell I would love to see sample for this pattern in an application. I've got some projects that could leverage it. Any way you could put a sample of that in Github or Codeplex for reference? While I get that most of that is somewhat documented in AM's wiki and unit tests, the scenarios are not cohesive, as they illustrate only one of the different features and patterns you described when using AM with a DI container in an application. – Thiago Silva Jul 18 '14 at 16:51

1 Answers1

1

Just create a function to do this for you somewhere in your initialisation code

void CreateMapWithServiceLocator<T1,T2>()
{
     Mapper.CreateMap<T1,T2>().ConstructUsingServiceLocator();
} 
gls123
  • 5,467
  • 2
  • 28
  • 28