5

NDC で Bob Martin のエピソードを見終わったところです。彼は、ページの上部にある C# の "using" ディレクティブは、コンポーネント間で作成/暗示される密結合のために悪いと言っていました。

プロジェクト参照と using ステートメントを追加せずに、外部の .dll を使用するにはどのような方法がありますか?

V6 では、ProgId の文字列でオブジェクトを作成できたのを覚えています。それが私が探している手法かどうかはわかりませんが、プロジェクト参照を使用する必要のない言語の例です。 dll.

編集:これは会議へのリンクです。申し訳ありませんが、プレゼンテーションの正確な引用または議事録はありません。記憶によるものです。

4

5 に答える 5

7

Bob Martin は、実際にはアーリー バインディングとレイト バインディングについて言及していると思います。

.NET では、リフレクション、より具体的には、ファイル名またはアセンブリ名を使用して外部アセンブリで型を作成できる Activator クラスを介してレイト バインディングが可能です。

通常、using ディレクティブ (using ステートメントではない) は、外部アセンブリを直接参照することと密接に関連しています。すなわち。アセンブリへの参照を追加してから、using ディレクティブを追加して、外部型を使用するときに完全な名前空間階層を入力する必要がないようにします。

そのため、コードの上部に多数の using ディレクティブがあることがわかった場合は、他の多くの型を直接参照している可能性があり、これらの型に対するコードの結合/依存関係が増加しています。

これが、ボブが彼らを悪いと言っている理由だと思います。「これは本当に悪いのか?」という質問に対する答え。非常に主観的で文脈に依存するものです。

ただし、一般に、コンポーネントの分離は、ほとんどの場合、ソフトウェアの設計において目指すべき適切な目標です。これは、システムの残りの部分への影響を最小限に抑えて、システムの一部を変更できるためです。Bob Martins の本を 1 冊か 2 冊読んだことがあれば、彼が目指しているのはこれだと思います。

于 2009-09-10T11:46:01.300 に答える
6

using ステートメント自体が悪いわけではありませ

のようなステートメントusing System;自体が問題になることはめったにありませんが、同じコード ファイル内に多数 (どれに応じて 3 ~ 6 を超えると思いますか) ある場合は、密結合を示している可能性があります。

同様の経験則をプロジェクト自体の参照数に適用することもできます。

密結合の解決策は、インターフェイスと依存性注入 (DI) へのプログラミングです。

VB から覚えていることを行う ProgId の方法は、単純に COM の動作でした。要するに、その ProgId を使用して、目的のインターフェイスを実装したインスタンスへの参照を取得しました。欠点は、COM オブジェクトがユニバーサルに登録されている場合にのみ機能することでした。dll地獄を覚えていますか?

DI の特定のフレーバーを使用して同じ原則を引き続き適用できますが、インターフェイスが .NET 型であり、IDL で定義されていないため、具体的な実装を提供するためにある種の DI コンテナーが必要になるだけです。

于 2009-09-10T11:53:05.110 に答える
6

using名前空間への単なるショートカットであり、外部ファイルへの参照ではありません。したがって、これは本当に意味がありません。

とにかく、インターフェイス DLL (インターフェイスのみを持つ DLL) を使用して、さまざまなアセンブリを動的に読み込んで使用し、既知のインターフェイスにキャストできる型を (リフレクションを通じて) 作成することができます。これは、厳密に型指定された言語と事前バインディングの利点を維持しながら、外部参照を緩める適切な方法です。

アセンブリをロードするためのAssemblyクラスとAppDomainクラス、および型インスタンスを名前で作成するためのActivatorをご覧ください。

于 2009-09-10T11:42:11.000 に答える
2

リフレクションを使用できます:

// Load the assembly
Assembly assembly = Assembly.LoadFrom(@"c:\path\Tools.dll");
// Select a type
Type type = assembly.GetType("Tools.Utility");
// invoke a method on this type
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]);
于 2009-09-10T11:47:06.243 に答える
1

リフレクションを通じて、あなたが言及していることを行うことができます。実行時にアセンブリをロードし、それを反映してクラスなどを取得し、それらを動的に呼び出すことができます。

個人的には、結合を避けるためにこれを行いません。私にとって、これはリフレクションの悪い使い方であり、そうしない特別な理由がない限り、むしろそれをプロジェクトに追加して参照したいと思います。リフレクションはシステムにオーバーヘッドを追加し、コンパイル時の安全性の利点を得られません。

于 2009-09-10T11:46:47.980 に答える