具有构造函数参数的AutoMapping对象

时间:2018-01-31 21:19:54

标签: c# automapper

我正在尝试配置AutoMapper以使用需要构造函数参数的类。我已经对此进行了相当多的在线研究,并找到了几个例子......但是他们要么不使用基于实例的AutoMapper,要么使用旧版本的AutoMapper。

我正在使用AutoMapper深度克隆对象。这是我创建的个人资料:

public class ScannerAutoMapProfile : Profile
{
    public ScannerAutoMapProfile()
    {
        CreateMap<AzureConfiguration>();
        CreateMap<CommunityUser>();
        CreateMap<Community>();
        CreateMap<Contact>();
        CreateMap<DatabaseConnection>();
        CreateMap<DatabaseConfiguration>();
        CreateMap<LoginManagement>();
        CreateMap<MaxLoadSeconds>();
        CreateMap<ScanTime>();
        CreateMap<ScanningAcceleration>();
        CreateMap<ScanningWindow>();
        CreateMap<ScanningInterval>();
        CreateMap<Scanning>();
        CreateMap<SearchParameterUser>();
        CreateMap<SearchParameter>();
        CreateMap<ScannerConfiguration>();
    }

    private void CreateMap<TModel>()
    {
        CreateMap<TModel, TModel>();
    }
}

ScannerConfiguration正在出现问题,它采用单个字符串参数。

这是我正在使用的Autofac模块:

public class AutoMapperModule : Module
{
    protected override void Load( ContainerBuilder builder )
    {
        base.Load( builder );

        var assemblies = AppDomain.CurrentDomain.GetAssemblies();

        builder.RegisterAssemblyTypes( assemblies )
            .Where( t => typeof(Profile).IsAssignableFrom( t ) && !t.IsAbstract && t.IsPublic )
            .As<Profile>();

        builder.Register( c => new MapperConfiguration( cfg =>
            {
                foreach( var profile in c.Resolve<IEnumerable<Profile>>() )
                {
                    cfg.AddProfile( profile );
                }
            } ) )
            .AsSelf()
            .SingleInstance();

        builder.Register( c => c.Resolve<MapperConfiguration>().CreateMapper( c.Resolve ) )
            .As<IMapper>()
            .SingleInstance();
    }
}

(感谢{至http://www.protomatter.co.uk/blog/development/2017/02/modular-automapper-registrations-with-autofac/)。

我可以成功实例化一个IMapper,它显示Autofac的工作正常。但是当我试图调用Map时:

_onDisk = Mapper.Map<ScannerConfiguration>( _inMemory );

它因“ScannerConfiguration没有无参数构造函数”异常而失败。

不幸的是,虽然我很确定我需要为Map()调用提供一些选项,但我还是无法弄清楚如何去做。我需要传递给构造函数的参数是ScannerConfiguration的公共属性,称为SourceFilePath。

2 个答案:

答案 0 :(得分:1)

由于ScannerConfiguration需要参数,为什么不自己初始化?

var sc = new ScannerConfiguration("some string value");
_onDisk = Mapper.Map( _inMemory, sc );

答案 1 :(得分:1)

如果Automapper无法使用默认构造函数创建目标实例,则可以为Automapper提供一个调用构造函数的函数,并返回带有ConstructUsing的新实例。构造对象后,它会像往常一样继续映射。

例如,这是源类和目标类。如果不调用非默认构造函数,则无法创建目标类:

public class SourceClass
{
    public string SourceStringProperty { get; set; }
    public int OtherSourceProperty { get; set; }
    public bool SameNameInBoth { get; set; }
}

public class DestinationClass
{
    public DestinationClass(string destinationString)
    {
        DestinationStringPropertyFromConstructor = destinationString;
    }

    public string DestinationStringPropertyFromConstructor { get; }
    public int OtherDestinationProperty { get; set; }
    public bool SameNameInBoth { get; set; }
}

映射看起来像这样:

Mapper.Initialize(cfg =>
{
    cfg.CreateMap<SourceClass, DestinationClass>()

        .ConstructUsing(hasString => new DestinationClass(hasString.SourceStringProperty))

        .ForMember(dest => dest.OtherDestinationProperty,
            opt => opt.MapFrom(src => src.OtherSourceProperty));
});

我添加了其他属性只是为了演示除了指定构造函数之外,其他配置细节都是相同的。