職場にて。質問を受けたのですが、即答できなかったので調べました。以前も同じような調べ物をした覚えがあるのですが、記録していなかったので自分用メモもかねて。
ちなみに開発環境はVisual Studio 2005、.NET Framework 2.0です。
厳密名を持たないDLLを修正した場合
参照元アセンブリが「何でもいいからエラー無く動く」というだけであれば、厳密名を持たないDLLを修正しても、参照元は再ビルドせずDLLだけ上書き配布できます。ただし、以下のことに注意してください。
- Public Constなどで宣言した定数の値は参照元を再ビルドしないと反映されません。
- Public Enumなどで宣言した列挙型の実値は参照元を再ビルドしないと反映されません。
これらについては、ビルドが通ったからといって、また、参照元が動いたからといって油断しているとハマります。注意してください。
実験してみた(Public Shared ~ As Stringとメソッドの追加)
厳密名を持たないソリューションを作成、EXE形式のプロジェクトに、クラスライブラリタイプのプロジェクトを追加して、EXEプロジェクトからプロジェクト参照でDLLを参照。DLLにはPublic Sharedな文字列変数だけが用意されていて、参照もとはそれを呼んでフォーム上のラベルに設定するだけのプログラムを作りました。この程度なら10分もかからずに作れますよね。
DLL「Message.dll」の中身はこんなです。
Public Class Message Public Shared MessageString1 As String = "メッセージ1" End Class
EXEとDLLを適当なフォルダに置いて、プログラムが動くことを確認した後、DLLのソースを以下のように書き換えます。文字列提供用メンバーは増えているわ、Functionは増えているわで大改造です(笑)。ついでに、AssemblyInfo.vbも書き換えてバージョン番号もメジャーバージョンを上げましょう。
Public Class Message Public Shared MessageString1 As String = "メッセージ1" Public Shared MessageString2 As String = "メッセージ2" Public Function GetMessage As String Return "メッセージ A" End Function End Class
で、DLLだけをビルドして、先ほどのEXEがあるフォルダに上書きコピー。動かすと……動きます。要するに、Public Sharedで宣言した変数などの変更であれば、DLLを書き換えてもDLLのビルドだけで動作上は問題ないということです。
実験してみた(定数と列挙型を持つDLLの場合)
次は、Public Constでの文字列宣言と、列挙型の宣言をDLL側で行い、それらの内容を変えた場合に何が起きるかを見てみます。先ほどはPublic Shared Stringで文字列を参照側に提供していましたが、今度は定数も増えています。列挙型も追加してみましょう。サンプルソースはこんな感じ。
動かすとこんな感じ。
これの各メンバーおよび列挙体のメンバー値をDLL側だけ変えて、ビルドし直さないEXEファイルのフォルダに配置して実行してみましょう。文字列系メンバーには「改」を付け、列挙型の値はすべて10を足しました。結果……
ほぅ……。定数(Const)は参照時に実際の値が埋め込まれ、動的にはDLLを見に行かないのですね。だから値が変わっていない。一方で、Public Shared宣言で公開した文字列変数は、動作時(実際はJITが動くとき?)に値が読み直されるので、DLL側の変更が反映されています。
そして、列挙型は何これ??コロンの左側はToStringをかけたもの、右側はメンバーをそのまま(あえて暗黙変換で文字列として)表示したものだったのですが、DLL差し替え後はどちらも一緒になってしまっています。値が変わらないだけならまだわかるのですが、なんで左側もこんなになったのかは別途調べますね。
結論:厳密名無しDLLで参照元全ビルドが必要なのは?
というわけで、共用するライブラリでPublicな定数等を宣言している場合は、全ビルドが必要です。逆に言うと、毎回の全ビルドを避けたいのであれば、以下の点に気をつける必要がありそうです。
- 固定値を宣言、共用したいのであれば、Public Shared … As String、といったShared宣言をうまく使う。
- 列挙型もDLL変更で全ビルドしないと反映されないので、列挙型のメンバー選定には十分気を遣う。なるべく変更せずにすむように設計する。
そのほかに参照元全ビルドが必要なのはどういうときか?
そのほかに全ビルドが必要なのは、ソースが以下の条件を両方満たしている場合です。
- 参照先のDLLに「厳密名」と呼ばれる、キッチリしたバージョン/参照管理を行うための情報がくっついている。
- DLLがビルドのたびにバージョン番号を変える運用になっていて、バージョン番号が変更された。
この場合、DLLのソース内容が変わっただけであれば呼び元(EXE側)の再ビルドは不要ですが、バージョン番号が変わった時点で参照できなくなります。これは、参照の際にDLLのバージョン番号までしっかり確認して「まさか不正なDLLと差し替えられたりしていないよな?」というチェックを行っているためです。
厳密名があってもバージョンが固定ならOKか?
結論から言うと、バージョン番号が変わらなければ、参照している側の再ビルドは不要なようです。ですが、実際の業務向けソース管理体制でバージョン管理を行わないという大きな問題が生じることから、あまり現実的な選択肢として検討しない方が良いと思います。
というわけで、たまにわからなくなって調べ直す情報のメモでした。
プログラミング .NET Framework 第3版 (マイクロソフト公式解説書)
- 作者: Jeffrey Richter,藤原雄介
- 出版社/メーカー: 日経BP社
- 発売日: 2011/02/03
- メディア: 大型本
- 購入: 10人 クリック: 500回
- この商品を含むブログ (20件) を見る
- 作者: ツァンタイ,ホァン・Q.ラム,Thuan Thai,Hoang Q. Lam,鷺谷好輝
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2002/08
- メディア: 単行本
- 購入: 2人 クリック: 20回
- この商品を含むブログ (4件) を見る