我们的测试机器上有个很奇怪的bug。错误是:
系统。来自程序集“activeviewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。
我就是不明白为什么。SetShort在DummyItem类中,我甚至重新编译了一个版本,写入事件日志,只是为了确保它不是部署/版本控制问题。奇怪的是,调用代码甚至不调用SetShort方法。
我们的测试机器上有个很奇怪的bug。错误是:
系统。来自程序集“activeviewer(…)”的类型“DummyItem”中的方法“SetShort”没有实现。
我就是不明白为什么。SetShort在DummyItem类中,我甚至重新编译了一个版本,写入事件日志,只是为了确保它不是部署/版本控制问题。奇怪的是,调用代码甚至不调用SetShort方法。
当前回答
I have yet another esoteric solution to this error message. I upgraded my target framework from .Net 4.0 to 4.6, and my unit test project was giving me the "System.TypeLoadException...does not have an implementation" error when I tried to build. It also gave a second error message about the same supposedly non-implemented method that said "The 'BuildShadowTask' task failed unexpectedly." None of the advice here seemed to help, so I searched for "BuildShadowTask", and found a post on MSDN which led me to use a text editor to delete these lines from the unit test project's csproj file.
<ItemGroup>
<Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>
在那之后,两个错误都消失了,项目建立起来了。
其他回答
在我的例子中,我试图使用TypeBuilder创建一个类型。TypeBuilder。CreateType抛出此异常。我最终意识到我需要添加MethodAttributes。在调用TypeBuilder时,将属性虚拟化。帮助实现接口的方法的DefineMethod。这是因为如果没有这个标志,该方法不会实现接口,而是实现一个具有相同签名的新方法(甚至没有指定MethodAttributes.NewSlot)。
我遇到了这个问题,只有我的本地机器有问题。我们组中的其他开发人员和我的VM都没有这个问题。
最后,这似乎与“目标群体”有关。 Visual Studio 2017
打开Visual Studio安装程序 选择修改 转到顶部的第二个标签“单个组件” 看看你选择了哪些框架和目标包。 我没有选择两个最新的目标包 我还注意到我没有“高级ASP”。NET特性”被选中,而其他机器也被选中。 选择并安装了新项目,现在一切都好了。
FWIW,当有一个配置文件重定向到引用程序集的不存在版本时,我得到了这个。融合日志为胜利而战!
当我尝试在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>()...
作为补充:如果更新用于生成假程序集的nuget包,也会发生这种情况。假设您安装了一个nuget包的V1.0版本,并创建了一个假程序集“fakeLibrary.1.0.0.0.Fakes”。接下来,更新到nuget包的最新版本,比如v1.1,它向接口添加了一个新方法。Fakes库仍在寻找该库的1.0版本。只需移除假组装和再生它。如果这是问题所在,这可能会解决它。