【问题标题】:How do I use AutoMapper to map via a constructor as well as resolving injected services如何使用 AutoMapper 通过构造函数进行映射以及解析注入的服务
【发布时间】:2020-11-16 13:19:13
【问题描述】:

我正在尝试使用 AutoMapper 在需要从构造函数而不是属性映射创建目标类型的两种类型之间进行映射。

复杂之处在于,虽然其中一个构造参数是我想从源映射的值,但第二个是我希望 Automapper 使用配置的 DI 容器解析的服务。

我曾尝试使用推荐的.ForCtorParam 方法,但如果我只指定第一个参数,我会收到以下运行时错误:

"目标需要有一个带有 0 个参数或只有可选参数的构造函数

我想我可能需要指定这两个参数,但我看不出如何指示映射器解析服务。

下面详细说明了我正在使用的类结构类型以及映射器的配置方式。

public class Source
{
   public string Value {get;set;}
}

public class Destination
{
    private IService _someService;

    public Destination(string value, IService someService)
    {
        Value = value;
        _someService = someService;
    }
    
    public string Value {get;}
}

public static class MapperFactory
{
   public static IMapper CreateMapper(IUnitContainer container)
   {
      var config = new MapperConfiguration(cfg => 
      {
          cfg.ConstructServicesUsing(type => container.Resolve(type));
     
          cfg.CreateMap<Source,Destination>().ForCtorParam("value", opt => opt.MapFrom(s => s.Value));
      });

      return config.CreateMapper();
    }
}

【问题讨论】:

    标签: c# unity-container automapper-10


    【解决方案1】:

    你必须使用构造函数吗?我使用自动映射器的每一种情况,都是没有构造函数的类,如果特定的属性需要特定的值,那么我就采用了这种方法(使用你的例子):

    cfg.CreateMap<Source,Destination>()
        .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.Value);
    

    如果您有特定的硬编码值需要通过构造函数传入,那么您只需使用 opt =&gt; opt.UseValue("hard-coded")

    您是否有一个您认为需要通过构造函数创建的类的具体示例?

    【讨论】:

    • 恐怕它确实如此,Automapper 看起来确实支持使用构造函数和解析容器提供的服务,但我不知道它是否可以同时实现。
    • @gouldos 使用容器指定参数怎么样? .ForCtorParam("someService", opt =&gt; opt.MapFrom(s =&gt; container.Resolve(typeof(ISomeService))));
    • 是的,这就是我采用的方法,试图在不必注入容器的情况下使代码更加分离,并认为结构映射已经支持解析参数本身。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 2017-08-02
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多