I have an N-Layer application as shown below
MyApp.Model - contains edmx and data models
MyApp.DataAccess - Repositories with EF
MyApp.Domain - Domain/business models
MyApp.Services - services(class library)
MyApp.Api - ASP.NET Web API
I am using Unity as my IoC container and Automapper for OO mapping.
My DataAccess layer references Model layer which contains all my Data objects.
I do not want to refer my model project in my Api layer. So returning DomainObjects (business models) from service layer and mapping to DTOs in API layer(DTOs are in API layer).
I configured domainModel to DTO mapping in API layer as below
public static class MapperConfig
{
public static void Configure() {
Mapper.Initialize(
config => {
config.CreateMap<StateModel, StateDto>();
config.CreateMap<StateDto, StateModel>();
//can't do this as I do not have reference for State which is in MyApp.Model
//config.CreateMap<State, StateModel>();
//config.CreateMap<StateModel, State>();
});
}
}
Now my question is how/where to configure my auto mapper mappings to convert my Entity models to Domain models?
To do in my API layer I do not have reference to my model project. I believe I should do this in service layer but not sure how to do that. Please help how to configure this mapping.
Note: Before asking here I googled with all eyes
Where to place AutoMapper map registration in referenced dll says to use static constructor which I do not think a good option to add in all my models (I have 100 models) and another answer says to use PreApplicationStartMethod for which I have to add reference to System.web.dll to my services which is not correct.
https://groups.google.com/forum/#!topic/automapper-users/TNgj9VHGjwg also did not answer my question properly.
Where do I configure AutoMapper? ¶ Configuration should only happen once per AppDomain. That means the best place to put the configuration code is in application startup, such as the Global.
If you have to do complex mapping behavior, it might be better to avoid using AutoMapper for that scenario. Reverse mapping can get very complicated very quickly, and unless it's very simple, you can have business logic showing up in mapping configuration.
AutoMapper is a ubiquitous, simple, convention-based object-to-object mapping library compatible with.NET Core. It is adept at converting an input object of one kind into an output object of a different type. You can use it to map objects of incompatible types.
You need to create mapping profiles in each of your layer projects, then tell AutoMapper to use those profiles in the topmost/outermost (invoking) layer that references all the lower layers. In your example:
MyApp.Model
public class ModelMappingProfile : AutoMapper.Profile
{
public ModelMappingProfile()
{
CreateMap<StateModel, StateDto>();
CreateMap<StateDto, StateModel>();
}
}
MyApp.Api
public class ApiMappingProfile : AutoMapper.Profile
{
public ApiMappingProfile()
{
CreateMap<State, StateModel>();
CreateMap<StateModel, State>();
}
}
MyApp.Services
Mapper.Initialize(cfg =>
{
cfg.AddProfile<MyApp.Model.ModelMappingProfile>();
cfg.AddProfile<MyApp.Model.ApiMappingProfile>();
});
or if you are using a DI container (e.g. SimpleInjector):
container.RegisterSingleton<IMapper>(() => new Mapper(new MapperConfiguration(cfg =>
{
cfg.AddProfile<MyApp.Model.ModelMappingProfile>();
cfg.AddProfile<MyApp.Model.ApiMappingProfile>();
})));
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