J'avais défini dans mon projet une configuration globale Automapper qui me permettrait d'utiliser Mapper.Map<targetType>(sourceObject);
dans mon code. (Voir ma configuration ci-dessous.)
J'ai mis à jour le paquet NuGet et je vois le message que Mapper.Map est obsolète/déprécié. Je suis retourné à Automapper sur GitHub et voir des exemples comme celui-ci:
[Test]
public void Example()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Source1, SubDest1>().FixRootDest();
cfg.CreateMap<Source2, SubDest2>().FixRootDest();
});
config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();
var subDest1 = mapper.Map<Source1, SubDest1>(new Source1 {SomeValue = "Value1"});
var subDest2 = mapper.Map<Source2, SubDest2>(new Source2 {SomeOtherValue = "Value2"});
subDest1.SomeValue.ShouldEqual("Value1");
subDest2.SomeOtherValue.ShouldEqual("Value2");
}
Est-ce que je vais devoir créer une configuration dans CHAQUE méthode qui utilise un mappage?
Ma configuration globale actuelle:
namespace PublicationSystem.App_Start
{
public class AutoMapperConfig
{
public static void CreateMaps()
{
CreateProjectMaps();
}
private static void CreateProjectMaps()
{
Mapper.CreateMap<Project, ProjectCreate>();
Mapper.CreateMap<Project, ProjectSelectable>();
//...
}
}
}
UPDATE: Grâce à un coaching de Scott Chamberlain, j'ai créé un cours comme celui-ci:
public class MkpMapperProfile : AutoMapper.Profile
{
protected override void Configure()
{
this.CreateMap<Project, ProjectCreate>();
this.CreateMap<Project, ProjectSelectable>();
this.CreateMap<Project, ProjectDetails>();
// Many Many other maps
}
}
Je pense que je devrais avoir la 'MapperConfiguration' dans ma classe BaseController. J'ai commencé à faire quelque chose comme ça:
public partial class BaseController : Controller
{
private MapperConfiguration mapConfig;
public BaseController()
{
db = new MkpContext();
SetMapperConfig();
}
private void SetMapperConfig()
{
mapConfig = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MkpMapperProfile>();
});
}
public BaseController(MapperConfiguration config)
{
db = new MkpContext();
this.mapConfig = config;
}
}
Suis-je sur la bonne voie?
Voici comment je l'ai géré.
Créez des cartes dans un profil en prenant soin d'utiliser la méthode CreateMap du profil plutôt que la méthode statique du même nom de Mapper:
internal class MappingProfile : Profile
{
protected override void Configure()
{
CreateMap<Project, ProjectCreate>();
}
}
Ensuite, chaque fois que des dépendances sont câblées (ex: Global.asax ou Startup), créez un MapperConfiguration puis utilisez-le pour créer un IMapper.
var mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new MappingProfile());
});
Ensuite, utilisez la configuration pour générer un IMapper:
var mapper = mapperConfiguration.CreateMapper();
Ensuite, enregistrez ce mappeur auprès du générateur de dépendances (j'utilise Autofac ici)
builder.RegisterInstance(mapper).As<IMapper>();
Maintenant, partout où vous avez besoin de mapper des choses, déclarez une dépendance sur IMapper:
internal class ProjectService : IProjectService {
private readonly IMapper _mapper;
public ProjectService(IMapper mapper) {
_mapper = mapper;
}
public ProjectCreate Get(string key) {
var project = GetProjectSomehow(key);
return _mapper.Map<Project, ProjectCreate>(project);
}
}
J'utilise la version 5.2.0, le support pour créer des cartes dans les constructeurs au lieu de remplacer configure.
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Project, ProjectDto>();
}
}
Dans Global.asax.cs, appelez comme suit:
Mapper.Initialize(c=>c.AddProfile<MappingProfile>());
J'espère que cette aide.
Ceci est nouveau dans AutoMapper 4.2. Jimmy Bogard a écrit un article sur ce sujet: Suppression de l'API statique d'AutoMapper . Il prétend que
L'interface IMapper est beaucoup plus légère, et le type sous-jacent est maintenant juste chargé d'exécuter des maps, en supprimant beaucoup de problèmes de threading ...
La nouvelle syntaxe: (collée depuis le blog)
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<User, UserDto>();
});
Si vous voulez juste la "vieille façon" de le faire. La dernière version 4.2.1 a ramené une certaine tradition. Juste utiliser
CreateMap<Project, ProjectCreate>();
au lieu de
Mapper.CreateMap<Project, ProjectCreate>();
L'ancien code fonctionnera parfaitement.
Vous pouvez trouver AutoMapper 4.2 configuré dans mon projet de modèle ASP.NET MVC ici: https://github.com/NikolayIT/ASP.NET-MVC-Template
Créez ces classes: https://github.com/NikolayIT/ASP.NET-MVC-Template/tree/master/ASP.NET%20MVC%205/Web/MvcTemplate.Web.Infrastructure/Mapping
Annotez les modèles de vue avec IMapFrom<>
: https://github.com/NikolayIT/ASP.NET-MVC-Template/blob/master/ASP.NET%20Core/Web/AspNetCoreTemplate.Web/ViewModels /Settings/SettingViewModel.cs
Utilisez-le comme .To<SomeViewModel>()
. Exemple: https://github.com/NikolayIT/ASP.NET-MVC-Template/blob/master/ASP.NET%20MVC%205/Web/MvcTemplate.Web/Controllers/HomeController.cs#L27
Mapper.Initialize(cfg => {
cfg.CreateMap<Source, Dest>();
});