AutoMappers AllowNullCollections设置是否可以限制为配置文件?

时间:2012-11-01 22:26:43

标签: automapper automapper-2

注意:我也在AutoMapper mailing list

上提出了这个问题

我的MVC应用程序基本上有两个映射级别(针对此问题进行了简化):

RepositoryObject <-> Entity <-> ViewModel

我们创建了两个配置文件,每个配置文件都处理相应映射级别的配置。

“RepositoryObjects”最终被序列化为XML并用于REST Web服务。我们发现的问题是RepositoryObject中的空集合将序列化为XML中的空元素,这会导致问题,因为Web服务要么没有元素,要么是包含数据的元素。

我们可以使用AllowNullCollections配置设置解决此问题。这将(当然)创建一个空集合而不是一个空集合,然后序列化很好。

然而,作为一个全球性的设置,我并不完全习惯,因为Jimmy has pointed out,这不是最好的做法。我很高兴在RepositoryObject <-> Entity映射中使用它,因为RepositoryObjects是自动生成的(无论如何都是丑陋的)并且它在应用程序中非常低级。但如果可能的话,我宁愿不“破坏”Entity <-> ViewModel映射。

那么,是否可以为每个配置文件配置此设置?

感谢。

更新

我在这里创建了测试代码:https://gist.github.com/4069909

复制此处以供参考:

ProfileClasses.cs

namespace NullCollectionIssue
{
    using System.Collections.Generic;

    public class SourceProfileOne
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class DestProfileOne
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class SourceProfileTwo
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class DestProfileTwo
    {
        public ICollection<string> Stuff { get; set; }
    }
}

AutoMapperConfigurator.cs

namespace NullCollectionIssue
{
    using AutoMapper;

    public class ProfileOne : Profile
    {
        public override string ProfileName
        {
            get
            {
                return "ProfileOne";
            }
        }

        protected override void Configure()
        {
            AllowNullCollections = true;
            Mapper.CreateMap<SourceProfileOne, DestProfileOne>();
        }
    }

    public class ProfileTwo : Profile
    {
        public override string ProfileName
        {
            get
            {
                return "ProfileTwo";
            }
        }

        protected override void Configure()
        {
            Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
        }
    }

    public static class AutoMapperConfigurator
    {
        public static void Configure()
        {
            Mapper.Initialize(x =>
            {
                x.AddProfile<ProfileOne>();
                x.AddProfile<ProfileTwo>();
            });
        }
    }
}

MappingTests.cs

namespace NullCollectionIssue
{
    using AutoMapper;

    using NUnit.Framework;

    [TestFixture]
    public class MappingTests
    {
        [Test]
        public void AutoMapper_Configuration_IsValid()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();
        }

        [Test]
        public void AutoMapper_ProfileOne_AllowsNullCollections()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();

            var source = new SourceProfileOne { Stuff = null };
            var dest = Mapper.Map<SourceProfileOne, DestProfileOne>(source);

            Assert.That(dest, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Null);
        }

        [Test]
        public void AutoMapper_ProfileTwo_DoesntAllowNullCollections()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();

            var source = new SourceProfileTwo { Stuff = null };
            var dest = Mapper.Map<SourceProfileTwo, DestProfileTwo>(source);

            Assert.That(dest, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Empty);
        }
    }
}

测试AutoMapper_Configuration_IsValidAutoMapper_ProfileTwo_DoesntAllowNullCollections通过,但测试AutoMapper_ProfileOne_AllowsNullCollections失败,因为dest.Stuff不为空。

2 个答案:

答案 0 :(得分:1)

查看此功能的source code of the initial commit,看来这是一个配置文件属性 - 请查看Profile.cs。

所以,我想,它应该适用于每个配置文件。我没试过。

答案 1 :(得分:1)

您收到此行为是因为您在configure方法中调用静态Mapper.Map

protected override void Configure()
{
    Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
}

应该是

protected override void Configure()
{
    CreateMap<SourceProfileTwo, DestProfileTwo>();//leading Mapper. removed
}