Skip to content

Commit

Permalink
Added ability to maps to specify how a row object is constructed.
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshClose committed Oct 14, 2012
1 parent 0b72752 commit a5ec825
Show file tree
Hide file tree
Showing 8 changed files with 606 additions and 504 deletions.
41 changes: 32 additions & 9 deletions src/CsvHelper.Tests/CsvClassMappingTests.cs
Expand Up @@ -92,17 +92,25 @@ public void MapMultipleNamesTest()
Assert.Equal( 3, map.PropertyMaps[1].NamesValue.Length );
Assert.Equal( 3, map.PropertyMaps[2].NamesValue.Length );

Assert.Equal("guid1", map.PropertyMaps[0].NamesValue[0]);
Assert.Equal("guid2", map.PropertyMaps[0].NamesValue[1]);
Assert.Equal("guid3", map.PropertyMaps[0].NamesValue[2]);
Assert.Equal( "guid1", map.PropertyMaps[0].NamesValue[0] );
Assert.Equal( "guid2", map.PropertyMaps[0].NamesValue[1] );
Assert.Equal( "guid3", map.PropertyMaps[0].NamesValue[2] );

Assert.Equal("int1", map.PropertyMaps[1].NamesValue[0]);
Assert.Equal("int2", map.PropertyMaps[1].NamesValue[1]);
Assert.Equal("int3", map.PropertyMaps[1].NamesValue[2]);
Assert.Equal( "int1", map.PropertyMaps[1].NamesValue[0] );
Assert.Equal( "int2", map.PropertyMaps[1].NamesValue[1] );
Assert.Equal( "int3", map.PropertyMaps[1].NamesValue[2] );

Assert.Equal("string1", map.PropertyMaps[2].NamesValue[0]);
Assert.Equal("string2", map.PropertyMaps[2].NamesValue[1]);
Assert.Equal("string3", map.PropertyMaps[2].NamesValue[2]);
Assert.Equal( "string1", map.PropertyMaps[2].NamesValue[0] );
Assert.Equal( "string2", map.PropertyMaps[2].NamesValue[1] );
Assert.Equal( "string3", map.PropertyMaps[2].NamesValue[2] );
}

[Fact]
public void MapConstructorTest()
{
var map = new TestMappingConstructorClass();

Assert.NotNull( map.Constructor );
}

private class TestClass
Expand All @@ -111,6 +119,21 @@ private class TestClass
public int IntColumn { get; set; }
public Guid GuidColumn { get; set; }
public string NotUsedColumn { get; set; }

public TestClass(){}

public TestClass( string stringColumn )
{
StringColumn = stringColumn;
}
}

private sealed class TestMappingConstructorClass : CsvClassMap<TestClass>
{
public TestMappingConstructorClass()
{
ConstructUsing( () => new TestClass( "String Column" ) );
}
}

private sealed class TestMappingDefaultClass : CsvClassMap<TestClass>
Expand Down
37 changes: 37 additions & 0 deletions src/CsvHelper.Tests/CsvReaderMappingTests.cs
Expand Up @@ -42,6 +42,22 @@ public void ReadMultipleNamesTest()
Assert.Equal( "two", records[1].StringColumn );
}

[Fact]
public void ConstructUsingTest()
{
var parserMock = new Mock<ICsvParser>();
parserMock.Setup( m => m.Configuration ).Returns( new CsvConfiguration() );
parserMock.Setup( m => m.Read() ).Returns( new[] { "1" } );

var csvReader = new CsvReader( parserMock.Object );
csvReader.Configuration.ClassMapping<ConstructorMappingClassMap>();

csvReader.Read();
var record = csvReader.GetRecord<ConstructorMappingClass>();

Assert.Equal( "one", record.StringColumn );
}

private class MultipleNamesAttributeClass
{
[CsvField( Names = new[] { "int1", "int2", "int3" } )]
Expand All @@ -50,5 +66,26 @@ private class MultipleNamesAttributeClass
[CsvField( Names = new[] { "string1", "string2", "string3" } )]
public string StringColumn { get; set; }
}

private class ConstructorMappingClass
{
public int IntColumn { get; set; }

public string StringColumn { get; set; }

public ConstructorMappingClass( string stringColumn )
{
StringColumn = stringColumn;
}
}

private sealed class ConstructorMappingClassMap : CsvClassMap<ConstructorMappingClass>
{
public ConstructorMappingClassMap()
{
ConstructUsing( () => new ConstructorMappingClass( "one" ) );
Map( m => m.IntColumn ).Index( 0 );
}
}
}
}
8 changes: 8 additions & 0 deletions src/CsvHelper/Configuration/CsvClassMap.cs
Expand Up @@ -3,7 +3,10 @@
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html
// http://csvhelper.com

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

namespace CsvHelper.Configuration
{
Expand All @@ -15,6 +18,11 @@ public abstract class CsvClassMap
private readonly CsvPropertyMapCollection propertyMaps = new CsvPropertyMapCollection();
private readonly List<CsvPropertyReferenceMap> referenceMaps = new List<CsvPropertyReferenceMap>();

/// <summary>
/// Gets the constructor expression.
/// </summary>
public virtual NewExpression Constructor { get; protected set; }

/// <summary>
/// The class property mappings.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/CsvHelper/Configuration/CsvClassMap`1.cs
Expand Up @@ -14,6 +14,15 @@ namespace CsvHelper.Configuration
/// <typeparam name="T">The <see cref="Type"/> of class to map.</typeparam>
public abstract class CsvClassMap<T> : CsvClassMap where T : class
{
/// <summary>
/// Constructs the row object using the given expression.
/// </summary>
/// <param name="expression">The expression.</param>
protected virtual void ConstructUsing( Expression<Func<T>> expression )
{
Constructor = ReflectionHelper.GetConstructor( expression );
}

/// <summary>
/// Maps a property to a CSV field.
/// </summary>
Expand Down

0 comments on commit a5ec825

Please sign in to comment.