Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automaticly resolve mappings #395

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/AutoMapper/AutoMapper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@
<Compile Include="TypeInfo.cs" />
<Compile Include="TypeMap.cs" />
<Compile Include="Internal\TypeMapFactory.cs" />
<Compile Include="Utility\IMapping.cs" />
<Compile Include="Utility\MappingResolver.cs" />
<Compile Include="Utility\OneWayMapping.cs" />
<Compile Include="Utility\TwoWayMapping.cs" />
<Compile Include="ValueFormatter.cs" />
<Compile Include="ValueResolver.cs" />
</ItemGroup>
Expand Down
13 changes: 13 additions & 0 deletions src/AutoMapper/Utility/IMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace AutoMapper.Utility
{
/// <summary>
///
/// </summary>
internal interface IMapping
{
/// <summary>
/// Configures the mapping.
/// </summary>
void ConfigureMapping();
}
}
37 changes: 37 additions & 0 deletions src/AutoMapper/Utility/MappingResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Linq;
using System.Reflection;

namespace AutoMapper.Utility
{
/// <summary>
///
/// </summary>
public class MappingResolver
{
/// <summary>
/// Resolves the OneWayMappings and TwoWayMappings in the specified assembly.
/// </summary>
/// <param name="assembly">The assembly.</param>
public static void Resolve(Assembly assembly)
{
var mappingTypes = assembly.GetTypes().Where(type =>
{
var baseType = type.BaseType;
if (baseType == null)
return false;

return baseType.IsAbstract &&
!baseType.IsInterface &&
baseType.IsGenericType &&
(baseType.GetGenericTypeDefinition() == typeof(OneWayMapping<,>) ||
baseType.GetGenericTypeDefinition() == typeof(TwoWayMapping<,>));
}).ToList();

foreach (var instance in mappingTypes.Select(mappingType => Activator.CreateInstance(mappingType) as IMapping))
{
instance.ConfigureMapping();
}
}
}
}
24 changes: 24 additions & 0 deletions src/AutoMapper/Utility/OneWayMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace AutoMapper.Utility
{
/// <summary>
/// Creates a one way mapping for the specified types
/// </summary>
/// <typeparam name="TSource">The type of the source.</typeparam>
/// <typeparam name="TDestination">The type of the destination.</typeparam>
public abstract class OneWayMapping<TSource, TDestination> : IMapping
{
/// <summary>
/// Configures the mapping.
/// </summary>
public void ConfigureMapping()
{
Configure(Mapper.CreateMap<TSource, TDestination>());
}

/// <summary>
/// Configures the specified mapping.
/// </summary>
/// <param name="mapping">The mapping.</param>
protected abstract void Configure(IMappingExpression<TSource, TDestination> mapping);
}
}
30 changes: 30 additions & 0 deletions src/AutoMapper/Utility/TwoWayMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace AutoMapper.Utility
{
/// <summary>
/// Creates a two way mapping for the specified types
/// </summary>
/// <typeparam name="TFirst">The type of the first.</typeparam>
/// <typeparam name="TSecond">The type of the second.</typeparam>
public abstract class TwoWayMapping<TFirst, TSecond> : IMapping
{
/// <summary>
/// Configures the mapping.
/// </summary>
public void ConfigureMapping()
{
Configure(Mapper.CreateMap<TFirst, TSecond>());
Configure(Mapper.CreateMap<TSecond, TFirst>());
}

/// <summary>
/// Configures the specified mapping.
/// </summary>
/// <param name="mapping">The mapping.</param>
protected abstract void Configure(IMappingExpression<TFirst, TSecond> mapping);
/// <summary>
/// Configures the specified mapping.
/// </summary>
/// <param name="mapping">The mapping.</param>
protected abstract void Configure(IMappingExpression<TSecond, TFirst> mapping);
}
}
1 change: 1 addition & 0 deletions src/UnitTests/UnitTests.Net4.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@
<Compile Include="Tests\TypeInfoSpecs.cs" />
<Compile Include="Tests\TypeMapFactorySpecs.cs" />
<Compile Include="TypeConverters.cs" />
<Compile Include="Utility\ResolverTest.cs" />
<Compile Include="ValueTypes.cs" />
<Compile Include="Bug\MappingToAReadOnlyCollection.cs" />
<Compile Include="WinRTExtensions.cs" />
Expand Down
79 changes: 79 additions & 0 deletions src/UnitTests/Utility/ResolverTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using AutoMapper.Utility;
using Should;
using Xunit;

namespace AutoMapper.UnitTests.Utility
{
public class ResolverTest
{
public class SimpleOne
{
public string Foo { get; set; }
}

public class SimpleTwo
{
public string Foo { get; set; }
}

public class OneWayMapping : OneWayMapping<SimpleOne, SimpleTwo>
{
protected override void Configure(IMappingExpression<SimpleOne, SimpleTwo> mapping)
{

}
}

[Fact]
public void ShouldBeAbleToResolveOneWayMapping()
{
Mapper.Reset();
MappingResolver.Resolve(typeof(OneWayMapping).Assembly);

var result = Mapper.Map<SimpleTwo>(new SimpleOne { Foo = "Unittest" });

result.ShouldNotBeNull();
result.Foo.ShouldEqual("Unittest");
}

public class First
{
public string Foo { get; set; }
}

public class Second
{
public string Foo { get; set; }
}

public class TwoWayMapping : TwoWayMapping<First, Second>
{
protected override void Configure(IMappingExpression<First, Second> mapping)
{

}

protected override void Configure(IMappingExpression<Second, First> mapping)
{

}
}

[Fact]
public void ShouldBeAbleToResolveTwoWayMapping()
{
Mapper.Reset();
MappingResolver.Resolve(typeof(TwoWayMapping).Assembly);

var firstResult = Mapper.Map<Second>(new First { Foo = "First foo" });

firstResult.ShouldNotBeNull();
firstResult.Foo.ShouldEqual("First foo");

var secondResult = Mapper.Map<First>(new Second { Foo = "Second foo" });

secondResult.ShouldNotBeNull();
secondResult.Foo.ShouldEqual("Second foo");
}
}
}