1

2个月前我问过这个问题!问题仍然存在。

我不打算在这里复制/粘贴相同的问题,因为我发现错误不是针对特定的 Entity-DTO 映射,而是针对控制器中首先出现的任何 Entity-DTO。

我的意思是,如果程序流到达 Country-CountryDto,则错误显示:

Missing type map configuration or unsupported mapping.

Mapping types: 
Country -> CountryDTO 
MyApp.Domain.BoundedContext.Country -> MyApp.Application.BoundedContext.CountryDTO

Destination path: 
List`1[0]

Source value: 
MyApp.Domain.BoundedContext.Country

或者,如果有第一手的帐户检查,错误会显示:

Missing type map configuration or unsupported mapping.

Mapping types:
Account -> AccountDTO
MyApp.Domain.BoundedContext.Account -> MyApp.Application.BoundedContext.AccountDTO

Destination path:
AccountDTO

Source value:
MyApp.Domain.BoundedContext.Account

我还发现,每当我重建 N 层解决方案的表示层(在本例中是 MVC 3 项目)时,错误就消失了。然后,在随机的时间,它再次发生。

如果这个问题只发生在开发环境中,那没什么大不了的,但是发布后问题仍然存在,所以我遇到了大麻烦。

我已经通过 Google、Stackoverflow、Automapper 论坛/组进行了搜索,但没有成功。

我还使用 Mapper.AssertConfigurationIsValid() 测试了映射,一切都很好。

我的项目是一个带有 Automapper 2.2 和 Unity IoC 的 MVC 3 项目。

再次,我将不胜感激任何想法、建议或解决方案。

编辑:好的,现在我有一个线索。我有一个名为 ManagementProfile 的配置文件,我的所有映射都在其中完成。在AutomapperTypeAdapterFactory()我有这样的代码:

public AutomapperTypeAdapterFactory()
    {
        //Scan all assemblies to find an Auto Mapper Profile
        var profiles = AppDomain.CurrentDomain.GetAssemblies()
                                .SelectMany(a => a.GetTypes())
                                .Where(t => t.BaseType == typeof(Profile));

        Mapper.Initialize(cfg =>
        {
            foreach (var item in profiles)
            {
                if (item.FullName != "AutoMapper.SelfProfiler`2")
                    cfg.AddProfile(Activator.CreateInstance(item) as Profile);
            }
        });
    }

我发现,通常,该profiles变量包含 ManagementProfile有时它无法获取信息并说"Enumeration yielded no results"我得到了这个问题中提到的异常。

通过进一步调查,我发现当一切正常时AppDomain.CurrentDomain.GetAssemblies()加载 85 个程序集,另一方面,当我收到异常时,它只加载了 41 个程序集,很明显,其中一个缺少的程序集是保存 DTO 映射的程序集。

4

3 回答 3

2

好的,我终于想通了。这:

AppDomain.CurrentDomain.GetAssemblies()

我的一段代码有时没有得到我的映射程序集,所以当它丢失时我得到一个错误。通过强制应用程序查找所有程序集来替换此代码解决了我的问题。

感谢您的回复。

编辑:Andrew Brown询问解决方案的代码时,我意识到我没有包含源代码片段。这是装配定位器:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Compilation;

public static class AssemblyLocator
{
    private static readonly ReadOnlyCollection<Assembly> AllAssemblies;
    private static readonly ReadOnlyCollection<Assembly> BinAssemblies;

    static AssemblyLocator()
    {
        AllAssemblies = new ReadOnlyCollection<Assembly>(
            BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList());

        IList<Assembly> binAssemblies = new List<Assembly>();

        string binFolder = HttpRuntime.AppDomainAppPath + "bin\\";
        IList<string> dllFiles = Directory.GetFiles(binFolder, "*.dll",
            SearchOption.TopDirectoryOnly).ToList();

        foreach (string dllFile in dllFiles)
        {
            AssemblyName assemblyName = AssemblyName.GetAssemblyName(dllFile);

            Assembly locatedAssembly = AllAssemblies.FirstOrDefault(a =>
                AssemblyName.ReferenceMatchesDefinition(
                    a.GetName(), assemblyName));

            if (locatedAssembly != null)
            {
                binAssemblies.Add(locatedAssembly);
            }
        }

        BinAssemblies = new ReadOnlyCollection<Assembly>(binAssemblies);
    }

    public static ReadOnlyCollection<Assembly> GetAssemblies()
    {
        return AllAssemblies;
    }

    public static ReadOnlyCollection<Assembly> GetBinFolderAssemblies()
    {
        return BinAssemblies;
    }
}

因此,我没有使用 AppDomain.CurrentDomain.GetAssemblies(),而是调用所提供的辅助类的 GetAssemblies() 方法,例如:

//Scan all assemblies to find an Auto Mapper Profile
//var profiles = AppDomain.CurrentDomain.GetAssemblies()
//                        .SelectMany(a => a.GetTypes())
//                        .Where(t => t.BaseType == typeof(Profile));
var profiles = AssemblyLocator.GetAssemblies().
                               SelectMany(a => a.GetTypes()).
                               Where(t => t.BaseType == typeof(Profile));
于 2013-05-27T11:42:20.420 回答
1

我最近有一个类似的问题。原来AutoMapper.Initialize在同一 AppDomain 中运行的代码中有多个调用(这是在 WCF 服务中)。这些调用将注册不同的映射。

AutoMapper.Initialize清除任何先前注册的映射,因此当多个线程同时运行时,配置会不时竞争并抛出错误,同时在单元和集成测试中运行良好。

因此,请扫描您的代码库以查找对AutoMapper.Initialize(and AutoMapper.Reset) 的调用,并确保只有一个调用。如果您需要在多个步骤中配置 AutoMapper,请使用AutoMapper.Configure后续步骤。

更多信息在这里

于 2013-04-30T15:58:32.373 回答
0

对我来说,这个错误与我CreateMap<>()打电话的地方有关。我已将它放在我的 DTO 的静态初始化程序中。当我将CreateMap<>()电话转移到不那么可爱的地方时,一切正常。

于 2015-03-05T16:42:18.080 回答