3

次のインターフェイスを定義するアプリケーション内にアセンブリがあります。

public void Method1()

次に、このインターフェイスを実装するアセンブリ プラグインがあります。実行時に検出され、ロードされます。

後で、インターフェイスを変更して新しいメソッドを含めました。

public void Method1()
public void Method2()

そして、新しいバージョンのインターフェイスを実装する新しいアセンブリ プラグインを作成しました。

新しいインターフェースと新しいプラグインのみをアプリケーションにデプロイする方法はありますか? 現在、クライアントは最初のプラグインで Method2() を呼び出すことはないため、問題になることはありません (最初のプラグインで Method2 が呼び出された場合はいつでも例外をスローしても問題ありません)。

私はそれができると思っていましたが、私は言っていTypeLoadExceptionます:

アセンブリ 'Provider2、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null' のタイプ 'Provider2.Class2' のメソッド 'Method2' には実装がありません。

(これは本当ですが、Method2 が呼び出されないので問題にはなりません)

4

2 に答える 2

8

そのインターフェイスを変更しないでください。

インターフェイスは通常、次の 2 つの主要な方法のいずれかで使用されます。

  1. それらはアプリケーションの内部で完全に使用されます
  2. それらは、他の人がインターフェースを実装または使用するプラグインなどのものを作成できるという意味で公開されています

最初のオプションでは、もちろん、新しいメソッドを追加するなど、好きなことを自由に行うことができます。それによって多くのコンパイラ エラーが発生する場合、それはあなた自身の問題であり、それらも「簡単に」修正できます。

2 番目のオプションでは、そのインターフェイスを変更しないでください。代わりに、新しいメソッドを使用して新しいインターフェイスを作成し、古いインターフェイスと新しいインターフェイスの両方をサポートするようにコードを記述する必要があります。

もちろん、古いクラスがまったく機能しないようにしたくない場合を除き、やりたいことをやり直すことになります。

したがって、ここでの答えは、そのインターフェースを変更すべきではないということです。代わりに、新しいメソッドを使用して新しいインターフェイスを作成し、古いバージョンと新しいバージョンの両方をサポートしてください。

インターフェイスを変更するときはいつでも、このアプローチを使用するように努める必要があります。これには、メソッドを追加するだけでなく、より多くの種類の変更が含まれます。

インターフェースの意味を変更したり、致命的ではない主要なバグを修正したりする場合は、新しいインターフェースを導入して、古いインターフェースに古いバグを持たせたいと思うかもしれません。誰かが、良いか悪いかにかかわらず、古い動作に依存するコードを書いた可能性があります。これを「修正」すると、コンパイラが文句を言わなくても、以前は機能していたものが壊れる可能性があります。

たとえば、比較の結果をメソッドに渡すとします。ドキュメントには、比較の結果が a の場合は値が負になり、 a の<場合は正の値になり、 a の場合は>0 になると記載されてい==ます。

その後、突然、-1、0、または +1 を返していないことに気付きます。-N、0、および +N を返しています。ここで、N は比較の副産物である数値です。たとえば、 の結果などですA-B。次のバージョンでは、これを -1、0、+1 に変更します。

一部のコードは、値が比較の結果以上のものを表しているという事実に依存している可能性がありますが、実際には-N.

もちろん、文書化されていない動作に依存することは常に悪いことですが、繰り返しになりますが、コードが以前は機能していたのに、更新によって機能が壊れたという事実に顧客が夢中になる可能性が高くなります

于 2013-09-09T07:05:06.107 に答える