自动映射器随机错误 [英] Automapper Random Errors

查看:101
本文介绍了自动映射器随机错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2个月前,我曾问过此问题!而且问题仍然存在.

2 months ago I have asked about this problem! and the problem still exists.

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

I am not going to copy/paste the same problem here because I found out that the error is not for a specific Entity-DTO mapping but for any Entity-DTO which is first in a controller.

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

I mean if the program flow hits to a Country-CountryDto, the error says:

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

或者如果第一手进行了帐户检查,则错误提示:

Or if there is an account check at first hand, the error says:

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项目),该错误就会消失.然后,在随机时间再次发生.

I also found that the error is gone whenever I rebuild the presentation layer (in this case it is an MVC 3 project) of my N-Layer solution. And then, at a random time, it happens again.

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

If this problem happened only in development environment it wouldn't be a big deal but after publishing the problem was still there so I am in big trouble.

我搜索过Google,Stackoverflow,Automapper论坛/组均未成功.

I have searched through Google, Stackoverflow, Automapper Forums/Groups with no success.

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

I have also tested the mappings with Mapper.AssertConfigurationIsValid() and everything was fine.

我的项目是带有Automapper 2.2和Unity IoC的MVC 3项目.

My project is an MVC 3 project with Automapper 2.2 and Unity IoC..

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

Again, I will appreciate any idea, advice or solution.

好,现在有了一个提示.我有一个名为ManagementProfile的配置文件,所有映射均已完成.在AutomapperTypeAdapterFactory()中,我有一个类似的代码:

OK, now I have a clue.. I have a profile called ManagementProfile where all my mappings are done. In the AutomapperTypeAdapterFactory() I have a code like:

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",我得到了这个问题中提到的异常.

I found that, normally, the profiles variable holds ManagementProfile but sometimes it couldn't get the information and says "Enumeration yielded no results" and I got the exception mentioned in this question.

经过进一步的研究,我发现当所有情况都很好时,AppDomain.CurrentDomain.GetAssemblies()会加载85个程序集,另一方面,当我遇到异常时,它仅加载41个程序集,很明显,缺少的一个程序集是保存DTO映射.

With further investigation I see that when everything is fine the AppDomain.CurrentDomain.GetAssemblies() loads 85 assemblies and on the other hand when I get the exception it has loaded only 41 assemblies and it was obvious that one of the missing assemblies was the one that holds the DTO mappings.

推荐答案

好,我终于明白了.

AppDomain.CurrentDomain.GetAssemblies()

我的代码有时有时无法获取我的映射程序集,因此在丢失时会出现错误.通过强制应用程序查找所有程序集来替换此代码,从而解决了我的问题.

piece of my code sometimes does not get my mapping assembly so while it is missing I get an error. Replacing this code by forcing the app to find all assemblies solved my problem.

感谢您的答复.

Andrew Brown 询问解决方案的代码时,我意识到我还没有包含源代码片段.这是AssemblyLocator:

As Andrew Brown asked about the code of the solution, I realized that I have not included the source code snippet. Here is the AssemblyLocator:

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()方法,例如:

Hence, instead of using AppDomain.CurrentDomain.GetAssemblies(), I am calling the GetAssemblies() method of the provided helper class like:

//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));

这篇关于自动映射器随机错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆