Asp.net core 如何将服务从.net core di容器传递到使用automapper创建的新对象

Asp.net core 如何将服务从.net core di容器传递到使用automapper创建的新对象,asp.net-core,asp.net-core-mvc,automapper,asp.net-core-webapi,asp.net-core-2.0,Asp.net Core,Asp.net Core Mvc,Automapper,Asp.net Core Webapi,Asp.net Core 2.0,我面临一个场景,需要将asp.net核心DI容器中的服务注入到使用automapper创建的对象的构造函数中 我不知道这是否是最佳实践,但让我解释一下我正在努力实现的目标 我有一个asp.net核心mvc控制器,它接收一个模型参数,只是一个POCO,该模型需要转换为一个ViewModel类,其中包含一些业务逻辑、数据访问等,在该类对象中,我想从注入的服务中获取一些信息,这是我遇到问题的部分,无法确定如何将服务从控制器注入到最终的ViewModel 我现在的代码看起来像这样 NewGameMode

我面临一个场景,需要将asp.net核心DI容器中的服务注入到使用automapper创建的对象的构造函数中

我不知道这是否是最佳实践,但让我解释一下我正在努力实现的目标

我有一个asp.net核心mvc控制器,它接收一个模型参数,只是一个POCO,该模型需要转换为一个ViewModel类,其中包含一些业务逻辑、数据访问等,在该类对象中,我想从注入的服务中获取一些信息,这是我遇到问题的部分,无法确定如何将服务从控制器注入到最终的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>();
        }
    }
}
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
        }
    }
}
namespace MyProject.Service
{
    public class MapperProfile : Profile
    {
        public MapperProfile()
        {
            CreateMap<NewGameModel, NewGameViewModel>();
        }
    }
}
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();
        }
    }
}
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);
        }
    }
}
ASP.NET核心项目-GameController.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>();
        }
    }
}
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
        }
    }
}
namespace MyProject.Service
{
    public class MapperProfile : Profile
    {
        public MapperProfile()
        {
            CreateMap<NewGameModel, NewGameViewModel>();
        }
    }
}
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();
        }
    }
}
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);
        }
    }
}
名称空间MyProject.Service.Controllers
{
[路由(“api/[控制器]”)]
公共类游戏控制器:控制器
{
专用只读IConfiguration\u配置;
专用只读IMapper\u映射器;
公共游戏控制器(IConfiguration配置,IMapper映射器)
{
_配置=配置;
_映射器=映射器;
}
[HttpPost]
public IActionResult CreateNewGame([FromBody]NewGameModel模型)
{
如果(!model.IsValid)返回BadRequest();
//引发错误,因为未传递任何构造函数参数
//如何将IConfiguration传递到目标NewGameViewModel对象?
var viewModel=\u mapper.Map(model);
var result=viewModel.DoSomething();
返回CreatedAtRoute(“GetGame”,new{token=result.GameToken},result);
}
}
}

非常感谢您的帮助

更新配置文件,将配置作为注入依赖项,并在创建映射时使用
ConstructUsing

公共类MapperProfile:Profile{
公共映射配置文件(IConfiguration配置){
CreateMap()
.ConstructUsing(=>NewGameViewModel(config));
}
}

对于后面的方法,不推荐使用上面的方法,因为它在配置文件中有状态。相反,请使用
AutoMapper.Extensions.Microsoft.DependencyInjection
软件包并在您的启动中:

services.AddAutoMapper();
然后在您的配置文件中,只需告诉AutoMapper您希望使用容器构造目标对象:

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

然后,您的控制器可以依赖于
IMapper
,AutoMapper将使用DI容器构建视图模型,您对ASP.NET核心的配置将只是
services.AddAutoMapper()的一行

查看此项。仍然在试图弄清楚如何将配置放入配置文件中,但还有一个问题是,按照您的建议更改MapperProfile,并将服务传递给Startup中的构造函数参数。cs成功了,谢谢