我们的测试机器上有个很奇怪的bug。错误是:

系统。来自程序集“activeviewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。

我就是不明白为什么。SetShort在DummyItem类中,我甚至重新编译了一个版本,写入事件日志,只是为了确保它不是部署/版本控制问题。奇怪的是,调用代码甚至不调用SetShort方法。


当前回答

I had the same problem. I figured out that my assembly, which is loaded by the main program, had some references with "Copy Local" set to true. These local copies of references were looking for other references in the same folder, which did not exist because the "Copy Local" of other references was set to false. After the deletion of the "accidentally" copied references the error was gone because the main program was set to look for correct locations of references. Apparently the local copies of the references screwed up the sequence of calling because these local copies were used instead of the original ones present in the main program.

重要的信息是,出现此错误是因为缺少加载所需程序集的链接。

其他回答

在我的例子中,我以前在repo之外的兄弟文件夹中引用了一个mylib项目——让我们称之为v1.0。

|-- myrepo
|    |-- consoleApp
|    |-- submodules
|         |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)

后来我做了正确的,并通过一个git子模块使用它-让我们称之为v2.0。 然而,一个项目consoleApp没有正确更新。它仍然在我的git项目之外引用旧的v1.0项目。

令人困惑的是,尽管*。csproj显然是错误的,并且指向v1.0, Visual Studio IDE将路径显示为v2.0项目! F12来检查接口和类也去了v2.0版本。

编译器放在bin文件夹中的程序集是v1.0版本,因此令人头疼。

IDE对我撒谎的事实让我很难意识到这个错误。

解决方案:从ConsoleApp中删除项目引用并读取它们。

一般提示:从头重新编译所有程序集(如果可能的话,当然不能用于nuget包),并检查bin\debug文件夹中的日期时间戳。任何过时的程序集都是你的问题。

当我尝试在dot net 5中使用自定义的AssemblyLoadContext(没有AppDomain创建)和共享类型(你需要使用它来调用插件方法而没有反射)实现插件程序集加载时,我得到了这个问题。这篇文章对我没有任何帮助。以下是我解决这个问题的方法:

为了允许调试插件加载没有问题-设置项目输出路径到主机应用程序bin文件夹。您将调试插件项目构建后得到的相同程序集。这可能是临时更改(仅用于调试)。 要修复TypeLoadException异常,你需要将所有“契约程序集”引用的程序集加载为共享程序集(运行时程序集除外)。检查加载器上下文实现(在构造函数中加载sharedAssemblies):


    public class PluginAssemblyLoadContext : AssemblyLoadContext
    {
        private AssemblyDependencyResolver _resolver;
        
        private IDictionary<string, Assembly> _loadedAssemblies;
        
        private IDictionary<string, Assembly> _sharedAssemblies;

        private AssemblyLoadContext DefaultAlc;

        private string _path;

        public PluginAssemblyLoadContext(string path, bool isCollectible, params Type[] sharedTypes)
             : this(path, isCollectible, sharedTypes.Select(t => t.Assembly).ToArray())
        {
        }

        public PluginAssemblyLoadContext(string path, bool isCollectible, params Assembly[] sharedAssemblies)
             : base(isCollectible: isCollectible)
        {

            _path = path;

            DefaultAlc = GetLoadContext(Assembly.GetExecutingAssembly()) ?? Default;

            var fileInfo = new FileInfo(_path);
            if (fileInfo.Exists)
            {
                _resolver = new AssemblyDependencyResolver(_path);

                _sharedAssemblies = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
                foreach (var a in sharedAssemblies.Distinct())
                {
                    LoadReferencedAssemblies(a);
                }

                _loadedAssemblies = new Dictionary<string, Assembly>();

                var assembly = LoadFromAssemblyPath(fileInfo.FullName);

                _loadedAssemblies.Add(fileInfo.FullName, assembly);
            }
            else
            {
                throw new FileNotFoundException($"File does not exist: {_path}");
            }
        }

        public bool LoadReferencedAssemblies(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (string.IsNullOrEmpty(assembly.Location))
            {
                throw new NotSupportedException($"Assembly location is empty string or null: {assembly.FullName}");
            }
            var alc = GetLoadContext(assembly);
            if (alc == this)
            {
                throw new InvalidOperationException($"Circular assembly loader dependency detected");
            }
            if (!_sharedAssemblies.ContainsKey(assembly.Location))
            {
                _sharedAssemblies.Add(assembly.Location, assembly);

                foreach (var an in assembly.GetReferencedAssemblies())
                {
                    var ra = alc.LoadFromAssemblyName(an);
                    LoadReferencedAssemblies(ra);
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public IEnumerable<Type> GetCommandTypes<T>()
        {
            var cmdType = typeof(T);
            return _loadedAssemblies.Values.SelectMany(a => a.GetTypes()).Where(t => cmdType.IsAssignableFrom(t));
        }

        public IEnumerable<T> CreateCommands<T>(Assembly assembly)
        {
            foreach (var cmdType in GetCommandTypes<T>())
            {
                yield return (T)Activator.CreateInstance(cmdType);
            }
        }

        protected override Assembly Load(AssemblyName assemblyName)
        {
            var path = _resolver.ResolveAssemblyToPath(assemblyName);
            if (path != null)
            {
                if (_sharedAssemblies.ContainsKey(path))
                {
                    return _sharedAssemblies[path];
                }
                if (_loadedAssemblies.ContainsKey(path))
                {
                    return _loadedAssemblies[path];
                }
                return LoadFromAssemblyPath(path);
            }     
            return DefaultAlc.LoadFromAssemblyName(assemblyName);
        }
    }

用法:


var loader = new PluginAssemblyLoadContext(fullPath, false, typeof(IPluginCommand));
loader.CreateCommands<IPluginCommand>()...

我也有这个错误,这是由任何CPU exe引用的任何CPU程序集,反过来引用x86程序集引起的。

异常抱怨MyApp中类的一个方法。实现(任何CPU),它派生了MyApp。接口(任何CPU),但在fuslogvw.exe中,我发现了一个隐藏的“试图从MyApp加载格式不正确的程序”异常。CommonTypes (x86),两者都使用它。

我在运行单元测试时也遇到了这个问题。应用程序运行良好,没有错误。 在我的案例中,问题的原因是我关闭了测试项目的构建。 重新启用我的测试项目的构建解决了这些问题。

当我的集成测试项目试图加载一个不包含接口依赖项解析的DLL时,我遇到了这个错误:

集成测试项目(参考主项目,但不是 StructureMap) 主要项目(引用StructureMap项目-使用 类构造函数中的接口) StructureMap项目(IoC - For().Use();)

这将导致抛出错误,因为它无法找到具体的实现。我在测试配置中排除了DLL,错误消失了