テストマシンに非常に奇妙なバグがあります。エラーは次のとおりです。
System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from Assembly 'ActiveViewers (...)' does not have an implementation.
理由が分からないだけです。 SetShort
はDummyItem
クラスにあり、展開/バージョン管理の問題ではないことを確認するために、イベントログへの書き込みを含むバージョンを再コンパイルしました。奇妙なことは、呼び出し元のコードがSetShort
メソッドさえも呼び出さないことです。
NOTE-この回答が役に立たない場合は、時間をかけて、人々が追加した他の回答をスクロールダウンしてください。
短い答え
これは、あるアセンブリのインターフェイスにメソッドを追加してから、別のアセンブリの実装クラスにメソッドを追加した場合に、インターフェイスアセンブリの新しいバージョンを参照せずに実装アセンブリを再構築すると発生します。
この場合、DummyItemは別のアセンブリからのインターフェイスを実装します。 SetShortメソッドは最近、インターフェイスとDummyItemの両方に追加されましたが、DummyItemを含むアセンブリは、以前のバージョンのインターフェイスAssemblyを参照して再構築されました。したがって、SetShortメソッドは効果的に存在しますが、インターフェイスの同等のメソッドにリンクする魔法のソースはありません。
ロングアンサー
これを再現してみる場合は、次を試してください。
クラスライブラリプロジェクト:InterfaceDefを作成し、クラスを1つだけ追加して、ビルドします。
public interface IInterface
{
string GetString(string key);
//short GetShort(string key);
}
2番目のクラスライブラリプロジェクトを作成します。実装(別のソリューションを使用)、InterfaceDef.dllをプロジェクトディレクトリにコピーし、ファイル参照として追加し、1つのクラスのみを追加して、ビルドします。
public class ImplementingClass : IInterface
{
#region IInterface Members
public string GetString(string key)
{
return "hello world";
}
//public short GetShort(string key)
//{
// return 1;
//}
#endregion
}
3番目のコンソールプロジェクトClientCodeを作成し、2つのdllをプロジェクトディレクトリにコピーし、ファイル参照を追加して、次のコードをMainメソッドに追加します。
IInterface test = new ImplementingClass();
string s = test.GetString("dummykey");
Console.WriteLine(s);
Console.ReadKey();
コードを1回実行すると、コンソールに「hello world」と表示されます
2つのdllプロジェクトのコードのコメントを解除して再構築します-2つのdllをClientCodeプロジェクトにコピーし、再構築して、再実行します。 ImplementingClassをインスタンス化しようとすると、TypeLoadExceptionが発生します。
質問者自身の回答が既に述べていることに加えて、次の点に注意する価値があります。これが発生する理由は、クラスがメソッドを実装せずにインターフェイスメソッドと同じシグネチャを持つメソッドを持つことができるためです。次のコードはそれを示しています。
public interface IFoo
{
void DoFoo();
}
public class Foo : IFoo
{
public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}
Foo foo = new Foo();
foo.DoFoo(); // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo(); // This calls the interface method
これは、エラーメッセージのメソッドが使用するクラスを定義する別のアセンブリへの参照がアプリケーションにないときに取得しました。 PEVerifyを実行すると、「システムが指定されたファイルを見つけることができません。」というより有用なエラーが発生しました。
私は同じメッセージに出くわしました、そして、ここで私たちが見つけたものです:私たちはプロジェクトでサードパーティのdllを使用します。これらの新しいリリースがリリースされた後、dllの新しいセットを指すようにプロジェクトを変更し、正常にコンパイルしました。
実行中にインターフェイスされたクラスの1つをインスタンス化しようとしたときに例外がスローされました。他のすべての参照が最新であることを確認しましたが、それでも運はありません。エラーメッセージのメソッドの戻り値の型が、参照されていない新しいアセンブリからの完全に新しい型であることを(オブジェクトブラウザーを使用して)発見するのにしばらく必要でした。
アセンブリへの参照を追加すると、エラーが消えました。
次のシナリオでこのエラーを受け取りました。
var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));
私にとっての修正は、アセンブリBのSystem.Web.Mvc参照を4.0.0.0にアップグレードすることでした。今明らかなようです!
オリジナルのポスターに感謝します!
このエラーが発生する可能性があるのは、署名されたアセンブリのバージョンが正しくない場合です。これはこの原因の通常の症状ではありませんが、ここに私が得たシナリオがあります
asp.netプロジェクトにはアセンブリAとアセンブリBが含まれ、Bには厳密な名前が付けられています
アセンブリAはActivator.CreateInstanceを使用してアセンブリCを読み込みます(つまり、個別にビルドされたCへの参照はありません)
Cは、現在存在するアセンブリBの古いバージョンを参照して構築されました
それが誰かを助けることを願っています-これを理解するのに私は年齢を要しました。
このエラーも発生しました。これは、x86アセンブリを参照するCPUアセンブリを参照するCPU exeが原因でした。
例外は、MyApp.Interfaces(任意のCPU)を派生させたMyApp.Implementations(任意のCPU)のクラスのメソッドについて文句を言いましたが、fuslogvw.exeでMyAppからの「不正な形式でプログラムをロードしようとする」例外を発見しました両方で使用される.CommonTypes(x86)。
このエラーメッセージには、もう1つの難解な解決策があります。ターゲットフレームワークを.Net 4.0から4.6にアップグレードし、ユニットテストプロジェクトをビルドしようとすると、「System.TypeLoadException ... does not have an implementation」エラーが表示されました。また、「 'BuildShadowTask'タスクが予期せず失敗しました」という、実装されていないと思われる同じメソッドに関する2番目のエラーメッセージも表示されました。ここでのアドバイスはどれも役に立たないようだったので、「BuildShadowTask」を検索したところ、 MSDNの投稿 が見つかりました。これにより、テキストエディターを使用してこれらの行を単体テストプロジェクトのcsprojファイルから削除しました。
<ItemGroup>
<Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>
その後、両方のエラーがなくなり、プロジェクトがビルドされました。
Autofacと多くの動的アセンブリロードを使用しているコンテキストでこのエラーが発生しました。
Autofac解決操作の実行中に、ランタイムはアセンブリの1つをロードできませんでした。エラーメッセージはMethod 'MyMethod' in type 'MyType' from Assembly 'ImplementationAssembly' does not have an implementation
を訴えました。この現象は、Windows Server 2012 R2 VMで実行中に発生しましたが、Windows 10またはWindows Server 2016 VMでnotが発生しました。
ImplementationAssembly
はSystem.Collections.Immutable
1.1.37を参照し、別のDefinitionAssembly
で定義されたIMyInterface<T1,T2>
インターフェイスの実装が含まれていました。 DefinitionAssembly
参照System.Collections.Immutable
1.1.36。
「実装されていない」IMyInterface<T1,T2>
のメソッドには、IImmutableDictionary<TKey, TRow>
で定義されているSystem.Collections.Immutable
型のパラメーターがありました。
プログラムディレクトリにあるSystem.Collections.Immutable
の実際のコピーはバージョン1.1.37でした。 Windows Server 2012 R2 VMでは、GACにSystem.Collections.Immutable
1.1.36のコピーが含まれていました。 Windows 10およびWindows Server 2016では、GACにはSystem.Collections.Immutable
1.1.37のコピーが含まれていました。ロードエラーは、GACに古いバージョンのDLLが含まれている場合にのみ発生しました。
そのため、アセンブリの読み込みエラーの根本的な原因は、System.Collections.Immutable
への参照の不一致でした。インターフェースの定義と実装には見た目は同じメソッドシグネチャがありましたが、実際にはSystem.Collections.Immutable
の異なるバージョンに依存していたため、ランタイムは実装クラスがインターフェース定義と一致するとは見なしませんでした。
次のバインディングリダイレクトをアプリケーション構成ファイルに追加すると、問題が修正されました。
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" />
</dependentAssembly>
私はこれに戻り続けます...ここでの答えの多くは、問題が何であるかを説明する素晴らしい仕事をしますが、それを修正する方法ではありません。
これに対する解決策は、プロジェクト公開ディレクトリ内のbinファイルを手動で削除することです。すべての参照をクリーンアップし、プロジェクトに最新のDLLの使用を強制します。
公開ツールの削除機能を使用することはお勧めしません。これは、IISを無効にする傾向があるためです。
「ダイヤモンド」型のプロジェクト依存関係でこれを取得しました:
私はプロジェクトAを再コンパイルしましたが、プロジェクトBはできませんでした。これにより、プロジェクトBはプロジェクトD dllの古いバージョンを「挿入」できました。
これは、プロジェクト(およびアセンブリ名)の名前を変更したときに発生しました。これは、ASP.NETプロジェクトに依存していました。 Webプロジェクトの型は、依存するアセンブリにインターフェイスを実装しました。 [ビルド]メニューから[クリーンソリューション]を実行しても、以前の名前のアセンブリはbin
フォルダーに残り、Webプロジェクトを実行したとき
var types = AppDomain.CurrentDomain.
GetAssemblies().
ToList().
SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;
上記の例外がスローされ、実装するWebタイプのインターフェースメソッドが実際に実装されていないと文句を言いました。 Webプロジェクトのbin
フォルダー内のアセンブリを手動で削除すると、問題が解決しました。
また、アセンブリの1つのユニットテスト中に以前にコードカバレッジを有効にしていたときに、このエラーが発生しました。何らかの理由で、新しいバージョンのインターフェイスを実装するために更新したにもかかわらず、Visual Studioはこの特定のDLLの古いバージョンを「バッファリング」しました。コードカバレッジを無効にすると、エラーがなくなりました。
ソリューションをMVC3からMVC5にアップグレードしたところ、ユニットテストプロジェクトから同じ例外を受け取り始めました。
古いファイルを探しているすべての参照を確認し、最終的にユニットテストプロジェクトでMvcのbindingRedirectsを実行する必要があることを発見しました。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
私の場合、WinForms Toolboxのリセットに役立ちました。
デザイナーでForm
を開くと例外が発生しました。ただし、コードのコンパイルと実行は可能であり、コードは期待どおりに動作しました。参照ライブラリの1つからインターフェイスを実装しているローカルUserControl
で例外が発生しました。このライブラリが更新された後にエラーが発生しました。
このUserControl
はWinFormsツールボックスにリストされていました。おそらく、Visual Studioが古いバージョンのライブラリの参照を保持しているか、古いバージョンをどこかにキャッシュしていた可能性があります。
この状況からどのように回復したかを以下に示します。
Reset Toolbox
]をクリックします。 (これにより、ツールボックスからカスタム項目が削除されます)。このエラーは、Assembly.LoadFrom(String)を使用してアセンブリがロードされ、Assembly.Load(Byte [])を使用して既にロードされたアセンブリを参照している場合にも発生する可能性があります。
たとえば、メインアプリケーションの参照アセンブリをリソースとして埋め込みましたが、アプリは特定のフォルダーからプラグインを読み込みます。
LoadFromを使用する代わりに、Loadを使用する必要があります。次のコードがジョブを実行します。
private static Assembly LoadAssemblyFromFile( String filePath )
{
using( Stream stream = File.OpenRead( filePath ) )
{
if( !ReferenceEquals( stream, null ) )
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read( assemblyData, 0, assemblyData.Length );
return Assembly.Load( assemblyData );
}
}
return null;
}
このエラーが発生したのは、フレームワークのバージョン4.5にあるアセンブリ 'C'にクラスがあり、フレームワークのバージョン4.5.1にあるアセンブリ 'A'にインターフェイスを実装し、アセンブリの基本クラスとして機能するためです。フレームワークのバージョン4.5.1にもあった「B」。システムは、アセンブリ 'B'をロードしようとしたときに例外をスローしました。さらに、3つのアセンブリすべてに.net 4.5.1を対象とするいくつかのnugetパッケージをインストールしました。なんらかの理由で、アセンブリの「B」でヌジェの参照が表示されていなくても、正常にビルドされていました。
実際の問題は、アセンブリがインターフェイスを含むnugetパッケージの異なるバージョンを参照しており、インターフェイスシグネチャがバージョン間で変更されていたことであることが判明しました。
FWIW、参照されているアセンブリの存在しないバージョンにリダイレクトする構成ファイルがあったときにこれを取得しました。 Fusionが勝利を記録します!
私の場合、以前はレポジトリ外の兄弟フォルダーにあるmylib
プロジェクトを参照していました。それをv1.0
と呼びましょう。
|-- myrepo
| |-- consoleApp
| |-- submodules
| |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)
後で適切に行い、gitサブモジュールを介して使用しました-v2.0
を呼び出します。ただし、1つのプロジェクトconsoleApp
は適切に更新されませんでした。私のgitプロジェクト以外の古いv1.0
プロジェクトをまだ参照していました。
混乱して、たとえ*.csproj
が明らかに間違っていてv1.0
を指していても、Visual Studio IDEはv2.0
プロジェクトとしてパスを示しました!インターフェイスとクラスを検査するF12は、v2.0
バージョンにも移行しました。
コンパイラーによってbinフォルダーに配置されたアセンブリはv1.0
バージョンであったため、頭痛の種でした。
IDEが私に嘘をついていたという事実は、エラーを認識するのをさらに難しくしました。
ソリューション:ConsoleApp
からプロジェクト参照を削除し、それらを再読み込みしました。
一般的なヒント:すべてのアセンブリを最初から再コンパイルし(可能な場合は、もちろんnugetパッケージにはできません)、bin\debug
フォルダーの日時スタンプを確認します。古い日付のアセンブリは問題です。
マネージC++に関連するこのタイプの問題の別の説明。
マネージC++を使用して作成されたアセンブリで定義され、特別な署名を持つインターフェイスをスタブしようとすると、スタブの作成時に例外が発生します。
これは、Rhino Mocks、およびおそらくSystem.Reflection.Emit
を使用するモックフレームワークに当てはまります。
public interface class IFoo {
void F(long bar);
};
public ref class Foo : public IFoo {
public:
virtual void F(long bar) { ... }
};
インターフェース定義は、次のシグネチャを取得します。
void F(System.Int32 modopt(IsLong) bar)
C++型のlong
はSystem.Int32
(またはC#では単にint
)にマッピングされることに注意してください。問題を引き起こしているのは、やや不明瞭なmodopt
です Ayende RahienがRhino Mocksメーリングリストで述べているように です。
私はほとんど同じ問題に直面しました。私はこのエラーの原因を頭にひっかいていました。私はクロスチェックを行い、すべてのメソッドが実装されました。
グーグルで、私は他の人の間でこのリンクを得ました。 @Paul McLinkのコメントに基づき、この2つの手順で問題は解決しました。
およびerror gone。
ありがとうポール:)
これがこのエラーに遭遇した人の助けになることを願っています:)
Visual Studio Pro 2008では、2つのプロジェクトが同じ名前のアセンブリを作成し、1つはクラスlib SDF.dllで、もう1つはアセンブリ名sdf.exeでlibを参照したときにこれを確認しました。参照するアセンブリの名前を変更すると、例外はなくなりました
私の場合、これは単に実装プロジェクトが古いことを意味します。インターフェイスを含むDLLは再構築されましたが、実装dllは古くなっていました。
X86ビルドタイプが選択されているため、WCFサービスでこれを取得しました。これにより、binがbinではなくbin\x86の下に置かれます。任意のCPUを選択すると、再コンパイルされたDLLが正しい場所に移動します(これが最初にどのように発生したかについては詳しく説明しません)。
このエラーについての私の見解を以下に示します。
extern
メソッドを追加しましたが、貼り付けに問題がありました。 DllImportAttribute
はコメントアウトされた行に置かれました。
/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
属性が実際にソースに含まれていることを確認すると、問題が修正されました。
ユニットテストの実行中にこの問題に遭遇しました。アプリケーションは正常に実行され、エラーは発生しませんでした。私の場合の問題の原因は、テストプロジェクトのビルドをオフにしたことです。テストプロジェクトのビルドを再度有効にすると、問題が解決しました。
今日このエラーが発生します。私の問題は-TFSで最新バージョンを取得しないことです。サーバーでは、メソッドの1つが変更されたインターフェイスを持つdllがありました。私は古いもので働いていた-私のPCでその作品。修正方法:最新版の入手、再構築
最近のWindowsの更新後にこのエラーを受け取りました。インターフェイスから継承するように設定されたサービスクラスがありました。インターフェイスには、C#のかなり新しい機能であるValueTupleを返すシグネチャが含まれていました。
私が推測できるのは、Windows Updateが新しいものをインストールしたことですが、明示的にそれを参照したり、バインディングリダイレクトを更新したりなどです...最終的な結果は、メソッドのシグネチャを単に「標準」に変更したことです。
補遺として:これは、偽のアセンブリを生成するために使用されたnugetパッケージを更新した場合にも発生する可能性があります。 nugetパッケージのV1.0をインストールし、偽のアセンブリ「fakeLibrary.1.0.0.0.Fakes」を作成するとします。次に、インターフェイスに新しいメソッドを追加したv1.1などのnugetパッケージの最新バージョンに更新します。 Fakesライブラリは、まだライブラリのv1.0を探しています。偽のアセンブリを削除して再生成するだけです。それが問題だった場合、おそらくこれで修正されます。
私の場合、TypeBuilder
を使用して型を作成しようとしました。 TypeBuilder.CreateType
はこの例外をスローしました。最終的に、インターフェイスの実装に役立つメソッドのMethodAttributes.Virtual
を呼び出すときに、属性にTypeBuilder.DefineMethod
を追加する必要があることに気付きました。これは、このフラグがない場合、メソッドはインターフェイスを実装せず、代わりに同じシグネチャを持つ新しいメソッドを(MethodAttributes.NewSlot
を指定しなくても)実装するためです。
同じ問題がありました。メインプログラムによって読み込まれるアセンブリには、「ローカルコピー」がtrueに設定されたいくつかの参照があることがわかりました。これらの参照のローカルコピーは、同じフォルダー内の他の参照を探していましたが、他の参照の「ローカルのコピー」がfalseに設定されていたため、存在しませんでした。 「誤って」コピーされた参照を削除した後、参照の正しい場所を探すようにメインプログラムが設定されていたため、エラーはなくなりました。どうやら、参照のローカルコピーは、メインプログラムに存在する元のコピーの代わりにこれらのローカルコピーが使用されたため、呼び出しのシーケンスを台無しにしました。
持ち帰りメッセージは、必要なアセンブリをロードするためのリンクがないためにこのエラーが表示されることです。
私はこれに遭遇し、私のローカルマシンだけが問題を抱えていました。私たちのグループの他の開発者も私のVMも問題はありませんでした。
最終的には、「ターゲットパック」Visual Studio 2017に関連しているように見えました
これを取得するさらに別の方法:
class GenericFoo<T> {}
class ConcreteFoo : GenericFoo<ClassFromAnotherAssembly> {}
ClassFromAnotherAssemblyのアセンブリを参照しないアセンブリのコード。
var foo = new ConcreteFoo(); //kaboom
ClassFromAnotherAssemblyがValueTupleであったときに、これは私に起こりました。
他の回答で説明されていないので、私の経験を追加してください:
MsTestで単体テストを実行すると、この問題が発生しました。
テスト対象のクラスは署名済みのアセンブリにありました。
このアセンブリの別のバージョンがたまたまGACにありました(ただし、同じアセンブリバージョン番号を使用)。
強力な名前付きアセンブリの依存関係解決アルゴリズムは、GACが最初にチェックされるため、署名なしとわずかに異なります。
そのため、MsTestはbinフォルダーのアセンブリを使用するのではなく、GACのアセンブリを選択し、それに対してテストを実行しようとしましたが、明らかに機能していませんでした。
解決策は、GACされたアセンブリを削除することでした。
ビルドが新しいアセンブリバージョン番号でアセンブリをコンパイルするため、テストの実行時にビルドサーバーでこれが発生していなかったということに注意してください。これは、GACのアセンブリの古いバージョンが選択されないことを意味しました。
また、何らかの理由でGACにアクセスできない場合、ここで潜在的な回避策を見つけました: https://johanleino.wordpress.com/2014/02/20/workaround-for-unit-testing-code-that -reside-in-the-gac /
Windowsの更新で問題が解決しました! Webアプリケーションは.Net 4.7.1およびc#7.0にあります。さまざまなウィンドウでテストしたところ、ウィンドウを更新することで問題が解決されることがわかりました。実際、この問題はWindows 10(バージョン1703)およびWindows Server 2012(昨年は更新されていません)でも見られました。両方を更新した後、問題は解決しました。実際、asp.netマイナーバージョン(C:\ Windows\Microsoft.NET\Framework64\v4.0.30319のclr.dllバージョンの3番目の部分)は、更新後に少し変更されました。
私にとって問題を解決したのは、Clean
とRebuild
the Solution
でした。