スマートクライアントと参照アセンブリ
WebサーバをリポジトリとしてアセンブリをダウンロードしてローカルPC上で実行するスマートクライアントがあったとする。(.NET2.0ではノータッチデプロイを改良したClickOnceという技術が追加されるが現状はClickOnceは使わない) このスマクラの実行アセンブリが次のようなアセンブリ依存関係を持っていたとしよう。なお、それぞれのアセンブリはGACにはインストールせず全てサイドバイサイド実行を想定している。(本当は各種設定ファイルも必要だが話を単純にするために無視している)
実行アセンブリ ├── アセンブリA └── アセンブリB上のような依存は実行アセンブリのアセンブリマニフェストに参照するアセンブリの名前として以下の様に記述される(ILのアセンブリディレクティブとして記述される)
.assembly extern アセンブリA { .ver バージョン } .assembly extern アセンブリB { .ver バージョン }
このようなアセンブリ構成の場合、Webサーバ上のリポジトリには"実行アセンブリ"、"アセンブリA"、"アセンブリB"の全てを配置しておき、クライアントは以下の手順で必要なアセンブリをダウンロードして実行することができるだろう。
これで万事OKなのだがリフレクション等を使ってアセンブリを動的にロードするようなアプリケーションの場合、困ったことになる。アセンブリの依存は以下のようになるのだが
実行アセンブリ ├── アセンブリA ── 実行時にアセンブリCをロード └── アセンブリB ── 実行時にアセンブリDをロード
こうすると当然だが必要とされるアセンブリCとアセンブリDはアセンブリマニフェスト上には依存するアセンブリとして記録されないので例えWebサーバ上のリポジトリにアセンブリCとDを配置していたとしても前述した手順中のAssembly#GetReferencedAssemblies()メソッドでは名前を拾えないのでダウンロード対象にはならないのだ。共有されるアセンブリ(ここではCとD)をGACに登録しておけばよさげであるが意地でもGACは使いたくない。となると
等の手段が考えられるがどっちも今ひとつ。
そこで調べてみると.NETの構成ファイルは依存するアセンブリを指定する語彙がスキーマに用意されているので以下のように書けばアセンブリマニフェストの参照アセンブリに依存アセンブリが追加されてくれないかな、と期待を込めたのだが...
- 構成ファイルのruntime要素で依存するアセンブリを指定する
<?xml version="1.0" ?>※ 属性:publicKeyTokenは設定していないアセンブリの場合は明示的にnullをセットしないとビルドすら通らなかった(2時間はまった..)
結果として上記の記述に対応するアセンブリディレクティブ(.assembly〜)は生成されなかった。この語彙はバージョン管理にだけ使用するらしい。
う〜ん、どうしたものか...
#追記#
最初に要件として書くべきでしたが、そもそもスマートクライアントでリフレクションを実現するためにはセキュリティの設定を大幅に緩くする必要がありますがこのエントリで言及するスマートクライアントを動かす環境はいわゆる"ローカルイントラネットで"の使用を前提にしており、全てのPCのアクセス許可セットはFullTrustに準じた運用しか考慮していません。