I'm rolling over my AutoMappers from using one large AutoMapperConfiguration class to using actual profiles. Global now looks like so (forgive the Open/Close violation for now)
Mapper.Initialize(x =>
{
x.AddProfile<ABCMappingProfile>();
x.AddProfile<XYZMappingProfile>();
// etc., etc.
});
The key piece that got me over the top and the hurdle that had previously always stopped me from using profiles was my ninject binding. I could never get the binding to work. Prior I had this binding:
Bind<IMappingEngine>().ToConstant(Mapper.Engine).InSingletonScope();
I've since migrated to this binding:
Bind<IMappingEngine>().ToMethod(context => Mapper.Engine);
This now works, the app is functional, I have profiles, and things are good.
The hitch is now in my unit tests. Using NUnit, I'd setup my constructor dependencies.
private readonly IMappingEngine _mappingEngine = Mapper.Engine;
and then in my [Setup] method I'd construct my MVC controller and call the AutoMapperConfiguration class.
[SetUp]
public void Setup()
{
_apiController = new ApiController(_mappingEngine);
AutoMapperConfiguration.Configure();
}
which I've now modified to.
[SetUp]
public void Setup()
{
_apiController = new ApiController(_mappingEngine);
Mapper.Initialize(x =>
{
x.AddProfile<ABCMappingProfile>();
x.AddProfile<XYZMappingProfile>();
// etc., etc.
});
}
Unfortunately, this does not seem to work. The mappings do not appear to be getting picked up as when I hit a method that uses mappings, AutoMapper throws an exception stating the mapping doesn't exist. Any suggestions on how/what to change the the mapper definition/injection in the test to resolve this? I'm guessing the definition of the IMappingEngine field is my problem but unsure of what options I have.
Thanks
Issue that you have is result of using static Mapper.Engine
which is some kind of singleton that contains configuration for AutoMapper. By convention, Mapper.Engine
should not be changed after it has been configured. So, if you'd like to configure Automapper by providing AutoMapper.Profiler
for each of unittest, you should avoid using it.
Changes are quite simple: add to instance your class AutoMapperConfiguration
it's own instance AutoMapper.MappingEngine
instead of using global static Mapper.Engine
.
public class AutoMapperConfiguration
{
private volatile bool _isMappinginitialized;
// now AutoMapperConfiguration contains its own engine instance
private MappingEngine _mappingEngine;
private void Configure()
{
var configStore = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());
configStore.AddProfile(new ABCMappingProfile());
configStore.AddProfile(new XYZMappingProfile());
_mappingEngine = new MappingEngine(configStore);
_isMappinginitialized = true;
}
/* other methods */
}
ps: full sample is here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With