Created
February 17, 2012 11:06
-
-
Save jochenjonc/1852705 to your computer and use it in GitHub Desktop.
Test that shows a bug when using AutoMapper with Castle Windsor 3.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace WindsorAutoMapper | |
{ | |
public class DummyEntity | |
{ | |
public string Name { get; set; } | |
public string FirstName { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using AutoMapper; | |
namespace WindsorAutoMapper | |
{ | |
public class DummyMapper : Mapper<DummyEntity, DummyModel> | |
{ | |
public DummyMapper(IConfiguration configuration, IMappingEngine mappingEngine) : base(configuration, mappingEngine) | |
{ | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace WindsorAutoMapper | |
{ | |
public class DummyModel | |
{ | |
public string NameFirstName { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace WindsorAutoMapper | |
{ | |
/// <summary> | |
/// Generic interface to implement a custom mapper | |
/// </summary> | |
/// <typeparam name="TSource">Source Type</typeparam> | |
/// <typeparam name="TDestination">Destination Type</typeparam> | |
public interface IMapper<in TSource, TDestination> | |
{ | |
/// <summary> | |
/// Map a source object to an destination object | |
/// </summary> | |
/// <param name="source">Source object</param> | |
/// <param name="destination">Destination object</param> | |
void Map(TSource source, TDestination destination); | |
/// <summary> | |
/// Map a source object to a new instance of the destination object | |
/// </summary> | |
/// <param name="source">Source object</param> | |
/// <returns>A new Destination object</returns> | |
TDestination Map(TSource source); | |
/// <summary> | |
/// Map a list of source objects to a new list of the destination objects | |
/// </summary> | |
/// <param name="source">List of source objects</param> | |
/// <returns>A new list of destination objects</returns> | |
IEnumerable<TDestination> Map(IEnumerable<TSource> source); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using AutoMapper; | |
namespace WindsorAutoMapper | |
{ | |
/// <summary> | |
/// Base Class to use when implementing a mapper | |
/// </summary> | |
/// <typeparam name="TSource">Source Type</typeparam> | |
/// <typeparam name="TDestination">Destination Type</typeparam> | |
public abstract class Mapper<TSource, TDestination> : IMapper<TSource, TDestination> | |
{ | |
private readonly IMappingExpression<TSource, TDestination> _mappingExpression; | |
private readonly IMappingEngine _mappingEngine; | |
/// <summary> | |
/// Create a mapper | |
/// </summary> | |
/// <param name="configuration">AutoMapper Configuration</param> | |
/// <param name="mappingEngine">AutoMapper Engine</param> | |
protected Mapper(IConfiguration configuration, IMappingEngine mappingEngine) | |
{ | |
_mappingExpression = configuration.CreateMap<TSource, TDestination>(); | |
_mappingEngine = mappingEngine; | |
} | |
/// <summary> | |
/// MappingExpression, use this to adjust the default mapping behavior | |
/// </summary> | |
protected IMappingExpression<TSource, TDestination> MappingExpression { get { return _mappingExpression; } } | |
/// <summary> | |
/// Map a source object to a destination object | |
/// </summary> | |
/// <param name="source">Source object</param> | |
/// <param name="destination">Destination object</param> | |
public void Map(TSource source, TDestination destination) | |
{ | |
_mappingEngine.Map(source, destination); | |
} | |
/// <summary> | |
/// Map a source object to a new instance of the destination object | |
/// </summary> | |
/// <param name="source">Source object</param> | |
/// <returns>A new destination object</returns> | |
public TDestination Map(TSource source) | |
{ | |
return _mappingEngine.Map<TSource, TDestination>(source); | |
} | |
/// <summary> | |
/// Map a list of source objects to a new list of the destination objects | |
/// </summary> | |
/// <param name="source">List of source objects</param> | |
/// <returns>A new list of destination objects</returns> | |
public IEnumerable<TDestination> Map(IEnumerable<TSource> source) | |
{ | |
return _mappingEngine.Map<IEnumerable<TSource>, IEnumerable<TDestination>>(source); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using AutoMapper; | |
using AutoMapper.Mappers; | |
using Castle.Facilities.TypedFactory; | |
using Castle.MicroKernel.Registration; | |
using Castle.Windsor; | |
using NUnit.Framework; | |
namespace WindsorAutoMapper | |
{ | |
[TestFixture] | |
public class WindsorAutomapperTestFixture | |
{ | |
private IWindsorContainer _container; | |
[TestFixtureSetUp] | |
public void SetupContainer() | |
{ | |
_container = new WindsorContainer(); | |
_container.Register( | |
// AutoMapper | |
Component.For<ConfigurationStore>() | |
.OnlyNewServices() | |
.ImplementedBy<ConfigurationStore>() | |
// .Properties(PropertyFilter.IgnoreAll) // Uncomment this line to fix the problem (https://groups.google.com/d/msg/castle-project-users/FotV-tBtGiQ/id31pps10EsJ) | |
.DependsOn( | |
Property.ForKey<ITypeMapFactory>().Eq(new TypeMapFactory()), | |
Property.ForKey<IEnumerable<IObjectMapper>>().Eq(MapperRegistry.AllMappers()) | |
), | |
Component.For<IConfigurationProvider>() | |
.OnlyNewServices() | |
.UsingFactoryMethod(kernel => kernel.Resolve<ConfigurationStore>()) | |
.LifeStyle.Singleton, | |
Component.For<IConfiguration>() | |
.OnlyNewServices() | |
.UsingFactoryMethod(kernel => kernel.Resolve<ConfigurationStore>()) | |
.LifeStyle.Singleton, | |
Component.For<IMappingEngine>() | |
.OnlyNewServices() | |
.ImplementedBy<MappingEngine>() | |
.LifeStyle.Singleton, | |
// Custom Mappers | |
AllTypes.FromThisAssembly() | |
.BasedOn(typeof (IMapper<,>)) | |
.WithService.FirstInterface() | |
.LifestyleSingleton() | |
); | |
} | |
[Test] | |
public void DummyMapperCanBeResolved() | |
{ | |
var mapper = _container.Resolve<IMapper<DummyEntity, DummyModel>>(); | |
Assert.That(mapper, Is.Not.Null); | |
} | |
[Test] | |
public void DummyMapperCanAlsoBeResolvedIfTheTypedFactoryFacilityIsRegistered() | |
{ | |
// By adding this the test fails | |
//Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not instantiate WindsorAutoMapper.DummyMapper | |
// ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. | |
// ----> Castle.MicroKernel.ComponentNotFoundException : No component for supporting the service System.String was found | |
_container.AddFacility<TypedFactoryFacility>(); | |
var mapper = _container.Resolve<IMapper<DummyEntity, DummyModel>>(); | |
Assert.That(mapper, Is.Not.Null); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment