2011-11-15 75 views
1

我遇到了使用AutoMapper和Windsor的問題。我創建了一個自定義類型轉換器,它依賴於另一個對象,可以從容器中解析該對象,但是當我嘗試在映射過程中使用轉換器時,會引發AutoMapper.AutoMapperMappingException,指出我的類型轉換器沒有默認構造函數。AutoMapper類型轉換器中的依賴項問題

我已經重建了問題的下面概念證明代碼:

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> 

測試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中工作。 –