Skip to content

Instantly share code, notes, and snippets.

@jochenjonc
Created February 17, 2012 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jochenjonc/1852705 to your computer and use it in GitHub Desktop.
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
namespace WindsorAutoMapper
{
public class DummyEntity
{
public string Name { get; set; }
public string FirstName { get; set; }
}
}
using AutoMapper;
namespace WindsorAutoMapper
{
public class DummyMapper : Mapper<DummyEntity, DummyModel>
{
public DummyMapper(IConfiguration configuration, IMappingEngine mappingEngine) : base(configuration, mappingEngine)
{
}
}
}
namespace WindsorAutoMapper
{
public class DummyModel
{
public string NameFirstName { get; set; }
}
}
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);
}
}
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);
}
}
}
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