Я столкнулся с проблемой при использовании AutoMapper и Windsor. Я создал пользовательский преобразователь типов, который зависит от другого объекта, который можно разрешить из контейнера, но когда я пытаюсь использовать преобразователь в процессе отображения, создается исключение AutoMapper.AutoMapperMappingExa, утверждая, что в моем преобразователе типов нет конструктор по умолчанию.
Я воссоздал проблему в коде подтверждения концепции ниже:
using System;
using System.Reflection;
using AutoMapper;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using NUnit.Framework;
public class ObjectOne
{
public string Name { get; set; }
public string Description { get; set; }
}
public class ObjectTwo
{
public string ObjName { get; set; }
public string ObjDescr { get; set; }
}
public interface ILoggingService
{
void Log(string message);
}
public class ConsoleLogger : ILoggingService
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
public class MyObjectConvertor : ITypeConverter<ObjectOne, ObjectTwo>
{
private readonly ILoggingService _loggingService;
public MyObjectConvertor(ILoggingService loggingService)
{
if (loggingService == null) throw new ArgumentNullException("loggingService");
_loggingService = loggingService;
}
public ObjectTwo Convert(ResolutionContext context)
{
_loggingService.Log(MethodBase.GetCurrentMethod().ToString());
var source = (ObjectOne)context.SourceValue;
return new ObjectTwo { ObjName = source.Name, ObjDescr = source.Description };
}
public void LogIt(string message)
{
_loggingService.Log(message);
}
}
public class MappingContractsWindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ILoggingService>().ImplementedBy<ConsoleLogger>(),
Component.For<MyObjectConvertor>());
}
}
[TestFixture]
public class MappingTester
{
private IWindsorContainer container;
[TestFixtureSetUp]
public void SetupFixture()
{
container = new WindsorContainer();
container.Install(new MappingContractsWindsorInstaller());
Mapper.CreateMap<ObjectOne, ObjectTwo>().ConvertUsing<MyObjectConvertor>();
Mapper.Configuration.ConstructServicesUsing(container.Resolve);
Mapper.AssertConfigurationIsValid();
}
[Test]
public void MyObjectConvertorReturnedWithLoggerInjectedOk()
{ // Proof that the Convertor is returned from the
// container with the dependency fulfilled
var conv = container.Resolve<MyObjectConvertor>();
conv.LogIt("Hello World");
}
[Test]
public void ObjectOneMapsToTwo()
{
var source = new ObjectOne()
{
Name = "Foo",
Description = "Bar"
};
var result = Mapper.Map<ObjectOne, ObjectTwo>(source);
Assert.That(result.ObjName == source.Name);
Assert.That(result.ObjDescr == source.Description);
}
}
При выполнении тестов во время ObjectOneMapsToTwo () выдается следующее исключение:
Test 'MappingTester.ObjectOneMapsToTwo' failed: AutoMapper.AutoMapperMappingException : Trying to map ObjectOne to ObjectTwo.
Using mapping configuration for ObjectOne to ObjectTwo
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
----> System.ArgumentException : Type 'MyObjectConvertor' does not have a default constructor
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
at AutoMapper.MappingEngine.Map(Object source, Type sourceType, Type destinationType, Action`1 opts)
at AutoMapper.MappingEngine.Map[TSource,TDestination](TSource source)
at AutoMapper.Mapper.Map[TSource,TDestination](TSource source)
Class1.cs(99,0): at MappingTester.ObjectOneMapsToTwo()
--ArgumentException
at System.Linq.Expressions.Expression.New(Type type)
at AutoMapper.DelegateFactory.<>c__DisplayClass1.<CreateCtor>b__0(Type t)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at AutoMapper.DelegateFactory.CreateCtor(Type type)
at AutoMapper.Mappers.ObjectCreator.CreateObject(Type type)
at AutoMapper.MappingExpression`2.<ConvertUsing>b__1a[TTypeConverter]()
at AutoMapper.DeferredInstantiatedConverter`2.Convert(ResolutionContext context)
at AutoMapper.MappingExpression`2.<>c__DisplayClass15.<ConvertUsing>b__14(ResolutionContext context)
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.CustomMapperStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
Этот проект ссылается на следующее:
<packages>
<package id="NUnit" version="2.5.10.11092" />
<package id="Castle.Core" version="2.5.2" />
<package id="Castle.Windsor" version="2.5.3" />
<package id="AutoMapper" version="2.0.0" />
</packages>
Тест MyObjectConvertorReturnedWithLoggerInjectedOk () проходит, подтверждая, что преобразователь типов возвращается из контейнера с зависимостью, переданной в OK. Но когда Automapper пытается использовать конвертер, он выдает исключение.
Любая помощь по этому вопросу будет принята.
Заранее спасибо.