2011-11-15 11 views
1

AutoMapperとWindsorを使用しているときに問題が発生しました。コンテナから解決できる別のオブジェクトに依存するカスタム型のコンバーターを作成しましたが、マッピングプロセスでコンバーターを使用しようとすると、AutoMapper.AutoMapperMappingExceptionがスローされ、型コンバーターにはデフォルトコンストラクタ。AutoMapper Type Convertorsの依存関係の問題

は、私は以下のコンセプト実証コードで問題を再現しました:

テストが実行されている場合は、以下の例外が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

これは実際にはAutoMapperのバグで、2.0リリース後に修正され、今後の2.1リリースでリリースされる予定です。あなたはナイトリーを引き下げて最新の安定したドロップを得ることができますAutoMapper.org

+0

私は私が怒っていると思ったように私はうれしいです。応答をありがとうJimmy –

+0

@Jimmy Bogardこの問題は今修正されましたか? NuGetのAutoMapper 2.1.266では依然として問題があるようです。 –

+0

これはAutoMapper 3.1.1.0で動作しています。 –

関連する問題