2011-11-15 3 views
1

AutoMapper 및 Windsor를 사용하는 동안 문제가 발생했습니다. 컨테이너에서 확인할 수있는 다른 개체에 따라 달라지는 사용자 지정 형식 변환기를 만들었지 만 매핑 프로세스에서 변환기를 사용하려고 할 때 AutoMapper.AutoMapperMappingException이 throw되고 형식 변환기에 해당 형식 변환기가없는 것으로 나타납니다. 기본 생성자.AutoMapper 유형 변환기의 종속성 문제

나는 아래 개념 증명 코드의 문제를 다시했습니다

테스트가 실행되면, 다음과 같은 예외가 ObjectOneMapsToTwo() 동안 발생합니다
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); 
    } 
} 

:

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> 

테스트 MyObjectConvertorReturnedWit hLoggerInjectedOk()가 전달되어 유형 변환자가 OK에서 전달 된 종속성을 가진 컨테이너에서 리턴되고 있음을 증명합니다. 그러나 Automapper가 컨버터를 사용하려고 시도하면 예외가 발생합니다.

이 문제에 대한 도움을 주시면 감사하겠습니다.

미리 감사드립니다.

답변

0

이것은 실제로 2.0 릴리스 이후에 수정 된 AutoMapper의 버그이며 곧 출시 될 2.1 릴리스에서 나옵니다. 최신 안정 드롭을 얻으려면 유흥가를 끌어 올 수 있습니다. AutoMapper.org

+0

나는 미치겠다 고 생각했기 때문에 기쁜 마음입니다. 응답 주셔서 감사합니다 Jimmy –

+0

@ Jimmy Bogard 지금이 문제가 해결 되었습니까? NuGet의 AutoMapper 2.1.266에서는 여전히 문제가있는 것으로 보입니다. –

+0

AutoMapper 3.1.1.0에서 작동합니다. –