Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Automaticly resolve mappings #395

Open
wants to merge 2 commits into from

3 participants

@JordyLangen

Hi,

I wrote this little code a while back for a project. It resolves mapping in an assembly using reflection. I thought it would be useful for other people as well.

Jordy Langen added some commits
@JordyLangen

On the other hand. It might be nicer to put the static Resolve method on the Mapper class, instead of the MappingResolver class and rename it to ResolveMappings

@jbogard jbogard modified the milestone: v.Future, v.Next
@thomaslevesque

What's the point of this? It can already be done by setting CreateMissingTypeMaps to true in the MappingOperationOptions.
(or maybe I misunderstood what your code does)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 1, 2013
  1. Added Mapping resolver classes

    Jordy Langen authored
  2. Added unittests for the resolver

    Jordy Langen authored
This page is out of date. Refresh to see the latest.
View
4 src/AutoMapper/AutoMapper.csproj
@@ -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>
View
13 src/AutoMapper/Utility/IMapping.cs
@@ -0,0 +1,13 @@
+namespace AutoMapper.Utility
+{
+ /// <summary>
+ ///
+ /// </summary>
+ internal interface IMapping
+ {
+ /// <summary>
+ /// Configures the mapping.
+ /// </summary>
+ void ConfigureMapping();
+ }
+}
View
37 src/AutoMapper/Utility/MappingResolver.cs
@@ -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();
+ }
+ }
+ }
+}
View
24 src/AutoMapper/Utility/OneWayMapping.cs
@@ -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);
+ }
+}
View
30 src/AutoMapper/Utility/TwoWayMapping.cs
@@ -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);
+ }
+}
View
1  src/UnitTests/UnitTests.Net4.csproj
@@ -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" />
View
79 src/UnitTests/Utility/ResolverTest.cs
@@ -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");
+ }
+ }
+}
Something went wrong with that request. Please try again.