1

Je suis confronté à un scénario où j'ai besoin d'injecter un service à partir du conteneur de base DI asp.net au constructeur d'un objet créé en utilisant automapper .Comment passer un service de .net core di container à un nouvel objet créé avec automapper

Je ne sais pas si c'est la meilleure pratique mais laissez-moi vous expliquer ce que j'essaie d'accomplir. J'ai un contrôleur mvc de base asp.net qui reçoit un paramètre de modèle, juste un POCO, ce modèle doit être converti en une classe ViewModel qui contient une certaine logique métier, accès aux données, etc., dans cet objet de classe que je veux pour obtenir des informations du service injecté, c'est la partie où j'ai des problèmes, je n'arrive pas à comprendre comment injecter le service du contrôleur au ViewModel final.

Mon code en ce moment ressemble à ceci.

NewGameModel.cs

namespace MyProject.Shared.Models 
{ 
    public class NewGameModel 
    { 
     public List<PlayerModel> Players { get; set; } 

     public bool IsValid => Players.Any(); 

     public NewGameModel() 
     { 
      Players = new List<PlayerModel>(); 
     } 
    } 
} 

NewGameViewModel.cs

namespace MyProject.Core.ViewModels 
{ 
    public class NewGameViewModel 
    { 
     private Guid Token = Guid.NewGuid(); 
     private DateTime DateTimeStarted = DateTime.Now; 
     private readonly IConfiguration _configuration; 

     public List<PlayerModel> Players { get; set; } 

     public NewGameViewModel(IConfiguration config) 
     { 
      _configuration = config; 
     } 

     public string DoSomething() 
     { 
      //Do something using _configuration 

      //Business Logic, Data Access etc 
     } 
    } 
} 

MapperProfile.cs

namespace MyProject.Service 
{ 
    public class MapperProfile : Profile 
    { 
     public MapperProfile() 
     { 
      CreateMap<NewGameModel, NewGameViewModel>(); 
     } 
    } 
} 

ASP.NET projet de base - Startup.cs

namespace MyProject.Service 
{ 
    public class Startup 
    { 
     public IConfiguration Configuration { get; } 

     public Startup(IConfiguration configuration) 
     { 
      Configuration = configuration; 
     } 

     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddMvc(); 
      services.AddSingleton(Configuration); 

      var autoMapperConfig = new MapperConfiguration(cfg => 
      { 
       cfg.AddProfile(new MapperProfile()); 
      }); 

      var mapper = autoMapperConfig.CreateMapper(); 

      services.AddSingleton(mapper); 
     } 

     public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
     { 
      if (env.IsDevelopment()) 
      { 
       app.UseDeveloperExceptionPage(); 
      } 

      app.UseMvc(); 
     } 
    } 
} 

ASP.NET projet de base - GameController.cs

namespace MyProject.Service.Controllers 
{ 
    [Route("api/[controller]")] 
    public class GameController : Controller 
    { 
     private readonly IConfiguration _configuration; 
     private readonly IMapper _mapper; 

     public GameController(IConfiguration config, IMapper mapper) 
     { 
      _configuration = config; 
      _mapper = mapper; 
     } 

     [HttpPost] 
     public IActionResult CreateNewGame([FromBody]NewGameModel model) 
     { 
      if (!model.IsValid) return BadRequest(); 

      //Throws error because no constructor parameter was passed  
      //How to pass the IConfiguration to the destination NewGameViewModel object? 

      var viewModel = _mapper.Map<NewGameModel, NewGameViewModel>(model); 

      var result = viewModel.DoSomething(); 

      return CreatedAtRoute("GetGame", new { token = result.GameToken }, result); 
     } 
    } 
} 

Je vous saurais gré de votre aide

+0

Check this out. https://stackoverflow.com/questions/7192275/how-to-use-automapper-to-construct-object-without-default-constructor – Nkosi

+0

Toujours en train d'essayer de comprendre comment obtenir la configuration dans le profil bien – Nkosi

+0

Voici une autre https://stackoverflow.com/questions/2239143/automapper-how-to-map-to-constructor-parameters-instead-of-property-setters#2239647 – Nkosi

Répondre

0

Mise à jour le profil de prendre la configuration en tant que dépendance injectée et utilisez ConstructUsing lors de la création du mappage.

public class MapperProfile : Profile { 
    public MapperProfile(IConfiguration config) { 
     CreateMap<NewGameModel, NewGameViewModel>() 
      .ConstructUsing(_ => new NewGameViewModel(config)); 
    } 
} 
+0

Modification de MapperProfile comme vous l'avez suggéré et transmission du service au paramètre constructeur dans le Startup.cs a fait l'affaire, Merci –

0

Pour ceux qui viennent plus tard, la méthode ci-dessus n'est pas préféré, car il a l'état des profils à l'intérieur. Au lieu de cela, utiliser le package AutoMapper.Extensions.Microsoft.DependencyInjection et à l'intérieur de votre démarrage:

services.AddAutoMapper(); 

ensuite dans votre profil, juste dire AutoMapper que vous voulez que votre objet de destination construit avec le conteneur:

public class MapperProfile : Profile 
{ 
    public MapperProfile() 
    { 
     CreateMap<NewGameModel, NewGameViewModel>() 
      .ConstructUsingServiceLocator(); 
    } 
} 

Votre contrôleur peut alors dépendre en IMapper et AutoMapper utilisera le conteneur DI pour construire le modèle de vue, et votre configuration à ASP.NET Core sera juste la ligne à services.AddAutoMapper();