【问题标题】:How to pass a service from .net core di container to a new object created with automapper如何将 .net core di 容器中的服务传递给使用 automapper 创建的新对象
【发布时间】:2017-10-02 20:50:52
【问题描述】:

我面临一个场景,我需要将服务从 asp.net core 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>();
        }
    }
}

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 Core 项目 - 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 Core 项目 - 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);
        }
    }
}

感谢您的帮助

【问题讨论】:

标签: asp.net-core asp.net-core-mvc automapper asp.net-core-webapi asp.net-core-2.0


【解决方案1】:

对于以后的人来说,上面的方法不是首选,因为它在配置文件中有状态。相反,请使用 AutoMapper.Extensions.Microsoft.DependencyInjection 包并在您的启动中:

services.AddAutoMapper();

然后在您的个人资料中,告诉 AutoMapper 您希望使用容器构建目标对象:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 按照您的建议更改 MapperProfile 并将服务传递给 Startup.cs 中的构造函数参数就可以了,谢谢
    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2023-03-17
    • 2016-06-27
    • 2012-03-16
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多