0

2 年前に、たとえば .NET クラス ライブラリを作成したとします。このmylib.dllライブラリは、foo.dllオープン ソース化され、MIT ライセンスを取得している .

多くの顧客が、私のライブラリとその依存関係アセンブリを使用していました。パッケージmylib.dll付きでしたfoo.dll

日が経ち、 の作成者はfoo.dllAPI を壊し、今では新しいバージョンのライブラリをデプロイしました。この新しいバージョンには、古いバージョンに含まれていた型のほとんどが含まれていますが、一部のメソッドが欠落しているか、変更されています。

問題

foo.dll一部の潜在的な消費者は、自分のアプリケーションで新しいバージョンを既に使用しています。私がそれらを供給するmylib.dllと、彼らはそれを使用できません。古いメソッドとシグネチャを備えmylib.dllた古いバージョンの が必要なため、ビルドを成功させることさえできません。foo.dll

この問題を克服するにはどうすればよいですか?

この問題が再び発生しないように、前方互換性のあるソリューションが必要です。だから私はいくつかのことを考えました:

  1. の新しいバージョンを使用するようにソース コードを更新しますfoo.dll。しかし、それには多くの手間と時間がかかります。さらに、この問題はいつか再び発生する可能性があるため、前方互換性はありません。
  2. の正確なバージョンのソースを持っているのでfoo.dll、名前空間を簡単に変更して全体を再構築できるかもしれません。このようにして、自分のバージョンの を楽しむことができます。これfoo.dllはライセンスが MIT であるため合法です。変更されたアセンブリmylib.foo.dllなどに名前を付けることができます。ILMergeのようなものを使用して全体をマージすることもできmylib.merged.dllます。
  3. mylib.dll必要な機能foo.dllがインターフェースと実装に分離されるように再設計します。エンジニアリングに関しては、これが最も洗練されたソリューションです。時間的には大惨事であり、真の解決策とは言えません。

私の質問

上記の #2 を達成するために、特定のソース コードの名前空間を変更する簡単な方法はありますか?

4

2 に答える 2

0

あはは!ええ - これは、nlog や newtonsoft などの人気のあるオープン ソース ライブラリの消費者の一般的な痛みです。

1. 複数の FOO.DLL を許可する

問題は、出力ディレクトリに DLL のコピーを 1 つしか含めることができないという事実に起因しています (すべてのバージョンが同じファイル名を共有しているため)。一部の製品では、DLL ファイル名にバージョン番号を入れてこれを解決していますが、これは見苦しいと思います。アセンブリ バインディング リダイレクトを使用して、DLL の依存関係を bin/subfolder に格納し、上書きを防ぐことができます。

2.イルマージ

顧客にとって最も簡単な解決策はアセンブリとその依存関係をマルチモジュール DLL にパッケージ化することです。つまり、ILMerge を使用して foo.dll を mylib.dll にマージします (はい、DLL には複数のアセンブリを含めることができます)。製品は依存関係がないように見えます (実際にはそうではありません。その依存関係はすべて 1 つの DLL で提供されているだけです!いいですね!)。

これは、foo.dll や名前空間の検索/置換を再コンパイルしようとするよりもはるかに優れたソリューションです。これは、依存関係のソース コードをいじったり、それを壊す危険を冒したりする必要がないためです...さらに、サード パーティのソース コードを変更し始めるとすぐに、これらの変更を維持する必要があります-新しいバージョンがリリースされたとき...ここでもう一度検索/置換します...

問題が解決しました。

警告: mylib.dll が foo.dll で宣言された型を呼び出し側プログラム (顧客のプログラム) に返した場合、DLL が異なるバージョンの型を想定しているため、クラスキャスト例外が発生する可能性があることに注意してください。したがって、この解決策は、foo.dll への依存関係がブラックボックスである (公開されていない) 場合にのみ推奨されます。ただし、これは問題ではないと思います。または、 FOO 型を別の名前空間に移動することを検討していないでしょう。

于 2013-04-10T21:58:22.163 に答える
0

新しいメソッドで欠落した古いメソッドの多くを使用しない場合foo.dll、実行可能な解決策は、コードを新しい にリンクし、古い関数からコピーできる欠落した関数を含むfoo.dllようなものを作成することです。ソースはオープンソースであり、MIT ライセンスを取得しているためです。mylib.foo.legacy.dllfoo

何をするにせよ、最新バージョンをfoo.dllベースとして使用すると、作成者が古い機能に戻る可能性はほとんどありません。古い dll からコピーしたレガシー メソッドを[obsolete]属性でマークすると、古い関数がまだ参照されている場所を示すコンパイル警告が表示されます。その後、レガシー dll を完全に削除できるようになるまで、これらの参照の削除に向けて時間をかけて作業することができます。

于 2013-04-10T08:18:34.700 に答える