如何将服务从 .net 核心 di 容器传递到使用 automapper 创建的新对象
How to pass a service from .net core di container to a new object created with automapper
我面临这样一种情况,我需要将服务从 asp.net 核心 DI 容器注入到使用 automapper 创建的对象的构造函数中。
我不知道这是否是最佳做法,但让我解释一下我要实现的目标。
我有一个 asp.net 核心 mvc 控制器,它接收模型参数,只是一个 POCO,该模型需要转换成包含一些业务逻辑、数据访问等的 ViewModel class ,在那个 class 对象中,我想从注入的服务中获取一些信息,这是我遇到问题的部分,无法弄清楚如何将服务从控制器注入到最终的 ViewModel。
此时我的代码看起来像这样。
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 核心项目 - 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 核心项目 - 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);
}
}
}
我会感谢你的帮助
更新配置文件以将配置作为注入的依赖项并在创建映射时使用 ConstructUsing
。
public class MapperProfile : Profile {
public MapperProfile(IConfiguration config) {
CreateMap<NewGameModel, NewGameViewModel>()
.ConstructUsing(_ => new NewGameViewModel(config));
}
}
对于后来的人来说,上面的方法不是首选,因为它在配置文件中有状态。相反,使用 AutoMapper.Extensions.Microsoft.DependencyInjection
包并在您的启动中:
services.AddAutoMapper();
然后在您的配置文件中,告诉 AutoMapper 您希望使用容器构建目标对象:
public class MapperProfile : Profile
{
public MapperProfile()
{
CreateMap<NewGameModel, NewGameViewModel>()
.ConstructUsingServiceLocator();
}
}
然后您的控制器可以依赖于 IMapper
,AutoMapper 将使用 DI 容器构建视图模型,您对 ASP.NET 核心的配置将只是对 [=14= 的一行]
我面临这样一种情况,我需要将服务从 asp.net 核心 DI 容器注入到使用 automapper 创建的对象的构造函数中。
我不知道这是否是最佳做法,但让我解释一下我要实现的目标。
我有一个 asp.net 核心 mvc 控制器,它接收模型参数,只是一个 POCO,该模型需要转换成包含一些业务逻辑、数据访问等的 ViewModel class ,在那个 class 对象中,我想从注入的服务中获取一些信息,这是我遇到问题的部分,无法弄清楚如何将服务从控制器注入到最终的 ViewModel。
此时我的代码看起来像这样。
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 核心项目 - 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 核心项目 - 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);
}
}
}
我会感谢你的帮助
更新配置文件以将配置作为注入的依赖项并在创建映射时使用 ConstructUsing
。
public class MapperProfile : Profile {
public MapperProfile(IConfiguration config) {
CreateMap<NewGameModel, NewGameViewModel>()
.ConstructUsing(_ => new NewGameViewModel(config));
}
}
对于后来的人来说,上面的方法不是首选,因为它在配置文件中有状态。相反,使用 AutoMapper.Extensions.Microsoft.DependencyInjection
包并在您的启动中:
services.AddAutoMapper();
然后在您的配置文件中,告诉 AutoMapper 您希望使用容器构建目标对象:
public class MapperProfile : Profile
{
public MapperProfile()
{
CreateMap<NewGameModel, NewGameViewModel>()
.ConstructUsingServiceLocator();
}
}
然后您的控制器可以依赖于 IMapper
,AutoMapper 将使用 DI 容器构建视图模型,您对 ASP.NET 核心的配置将只是对 [=14= 的一行]