Permalink
Browse files

Adding configuration to allow null destination collection types, closes

  • Loading branch information...
1 parent 4344a62 commit f3c28fe04b3cd36c99a2836a83b504233f4b9577 @jbogard committed Nov 7, 2011
@@ -49,6 +49,12 @@ public bool AllowNullDestinationValues
set { GetProfile(DefaultProfileName).AllowNullDestinationValues = value; }
}
+ public bool AllowNullCollections
+ {
+ get { return GetProfile(DefaultProfileName).AllowNullCollections; }
+ set { GetProfile(DefaultProfileName).AllowNullCollections = value; }
+ }
+
public INamingConvention SourceMemberNamingConvention
{
get { return GetProfile(DefaultProfileName).SourceMemberNamingConvention; }
@@ -78,6 +84,11 @@ bool IProfileConfiguration.MapNullSourceValuesAsNull
get { return AllowNullDestinationValues; }
}
+ bool IProfileConfiguration.MapNullSourceCollectionsAsNull
+ {
+ get { return AllowNullCollections; }
+ }
+
public IProfileExpression CreateProfile(string profileName)
{
var profileExpression = new Profile(profileName);
@@ -15,5 +15,6 @@ public interface IFormatterConfiguration : IProfileConfiguration
public interface IProfileConfiguration
{
bool MapNullSourceValuesAsNull { get; }
+ bool MapNullSourceCollectionsAsNull { get; }
}
}
@@ -12,7 +12,8 @@ public interface IFormatterExpression
void SkipFormatter<TValueFormatter>() where TValueFormatter : IValueFormatter;
IFormatterExpression ForSourceType<TSource>();
bool AllowNullDestinationValues { get; set; }
- }
+ bool AllowNullCollections { get; set; }
+ }
public interface IFormatterCtorExpression
{
@@ -44,6 +45,6 @@ public interface IConfiguration : IProfileExpression
void AddProfile(Profile profile);
void AddProfile<TProfile>() where TProfile : Profile, new();
void ConstructServicesUsing(Func<Type, object> constructor);
- void Seal();
+ void Seal();
}
}
@@ -9,5 +9,6 @@ public interface IMappingEngineRunner
string FormatValue(ResolutionContext context);
IConfigurationProvider ConfigurationProvider { get; }
bool ShouldMapSourceValueAsNull(ResolutionContext context);
+ bool ShouldMapSourceCollectionAsNull(ResolutionContext context);
}
}
@@ -26,6 +26,7 @@ public FormatterExpression(Func<Type, IValueFormatter> formatterCtor)
}
public bool AllowNullDestinationValues { get; set; }
+ public bool AllowNullCollections { get; set; }
public INamingConvention SourceMemberNamingConvention { get; set; }
public INamingConvention DestinationMemberNamingConvention { get; set; }
public Func<string, string> SourceMemberNameTransformer { get; set; }
@@ -146,6 +147,11 @@ public bool MapNullSourceValuesAsNull
get { return AllowNullDestinationValues; }
}
+ public bool MapNullSourceCollectionsAsNull
+ {
+ get { return AllowNullCollections; }
+ }
+
public void RecognizePrefixes(params string[] prefixes)
{
var orig = SourceMemberNameTransformer;
@@ -19,6 +19,9 @@ public bool IsMatch(ResolutionContext context)
public object Map(ResolutionContext context, IMappingEngineRunner mapper)
{
+ if (context.IsSourceValueNull && mapper.ShouldMapSourceCollectionAsNull(context))
+ return null;
+
var sourceEnumerableValue = (IEnumerable)context.SourceValue ?? new object[0];
IEnumerable<object> keyValuePairs = sourceEnumerableValue.Cast<object>();
@@ -10,6 +10,11 @@ public abstract class EnumerableMapperBase<TEnumerable> : IObjectMapper
{
public object Map(ResolutionContext context, IMappingEngineRunner mapper)
{
+ if (context.IsSourceValueNull && mapper.ShouldMapSourceCollectionAsNull(context))
+ {
+ return null;
+ }
+
ICollection<object> enumerableValue = ((IEnumerable) context.SourceValue ?? new object[0])
.Cast<object>()
.ToList();
@@ -374,6 +374,15 @@ bool IMappingEngineRunner.ShouldMapSourceValueAsNull(ResolutionContext context)
return ConfigurationProvider.MapNullSourceValuesAsNull;
}
+ bool IMappingEngineRunner.ShouldMapSourceCollectionAsNull(ResolutionContext context)
+ {
+ var typeMap = context.GetContextTypeMap();
+ if (typeMap != null)
+ return ConfigurationProvider.GetProfileConfiguration(typeMap.Profile).MapNullSourceCollectionsAsNull;
+
+ return ConfigurationProvider.MapNullSourceCollectionsAsNull;
+ }
+
private void ClearTypeMap(object sender, TypeMapCreatedEventArgs e)
{
IObjectMapper existing;
@@ -24,6 +24,12 @@ public bool AllowNullDestinationValues
set { GetProfile().AllowNullDestinationValues = value; }
}
+ public bool AllowNullCollections
+ {
+ get { return GetProfile().AllowNullCollections; }
+ set { GetProfile().AllowNullCollections = value; }
+ }
+
public INamingConvention SourceMemberNamingConvention
{
get { return GetProfile().SourceMemberNamingConvention; }
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
using Should;
using NUnit.Framework;
@@ -326,5 +328,79 @@ public void Should_allow_the_resolver_to_handle_null_values()
}
}
+ public class When_overriding_collection_null_behavior : AutoMapperSpecBase
+ {
+ private Dest _dest;
+
+ public class Source
+ {
+ public IEnumerable<int> Values1 { get; set; }
+ public List<int> Values2 { get; set; }
+ public Dictionary<string, int> Values3 { get; set; }
+ public int[] Values4 { get; set; }
+ public ReadOnlyCollection<int> Values5 { get; set; }
+ public Collection<int> Values6 { get; set; }
+ }
+
+ public class Dest
+ {
+ public IEnumerable<int> Values1 { get; set; }
+ public List<int> Values2 { get; set; }
+ public Dictionary<string, int> Values3 { get; set; }
+ public int[] Values4 { get; set; }
+ public ReadOnlyCollection<int> Values5 { get; set; }
+ public Collection<int> Values6 { get; set; }
+ }
+
+ protected override void Establish_context()
+ {
+ Mapper.Initialize(cfg =>
+ {
+ cfg.CreateMap<Source, Dest>();
+ cfg.AllowNullCollections = true;
+ });
+ }
+
+ protected override void Because_of()
+ {
+ _dest = Mapper.Map<Source, Dest>(new Source());
+ }
+
+ [Test]
+ public void Should_allow_null_ienumerables()
+ {
+ _dest.Values1.ShouldBeNull();
+ }
+
+ [Test]
+ public void Should_allow_null_lists()
+ {
+ _dest.Values2.ShouldBeNull();
+ }
+
+ [Test]
+ public void Should_allow_null_dictionaries()
+ {
+ _dest.Values3.ShouldBeNull();
+ }
+
+ [Test]
+ public void Should_allow_null_arrays()
+ {
+ _dest.Values4.ShouldBeNull();
+ }
+
+ [Test]
+ public void Should_allow_null_read_only_collections()
+ {
+ _dest.Values5.ShouldBeNull();
+ }
+
+ [Test]
+ public void Should_allow_null_collections()
+ {
+ _dest.Values6.ShouldBeNull();
+ }
+ }
}
}

0 comments on commit f3c28fe

Please sign in to comment.