#目的
ODACを利用してOracle DB(以下通じる場合はDBを省略)に接続するアプリケーションをVSで作成する場合、開発時にOracle.DataAccess.dllを参照する設定を行う。
アプリケーションの要件として複数のOracle(11g, 12c, 18c...)への接続が存在する場合、開発環境はどのような構成にすればよいかを考える。
#side-by-side実行におけるdll依存関係
@ITやMSのページで解説されているように、アプリケーションはside-by-sideで実行されるため、開発時に参照していたdllは、そのバージョンまでが一致していないとアプリケーションで利用されないという原則が存在している。
これは、意図していないdllを読み込むことに起因する実行時エラーを防ぐために必要な機能なのだが、Oracle.DataAccess.dllのようにアプリケーションと同梱して配置することが困難なdll(ライセンスの関係で、客先に配置してもらう必要があるため)を参照する際には注意が必要である。
#発行者ポリシーを用いたアセンブリバージョンのリダイレクト
side-by-side実行では、参照先と同じバージョンのdllしか読み込まれないのが原則だが、GACに登録されたdllを用いる場合、GAC内に発行者ポリシーファイルが存在すれば、使用するdllより新しいバージョンのdllを利用するように指定することが可能である。
アセンブリバージョンのリダイレクトや発行者ポリシーに関しては「アセンブリ バージョンのリダイレクト」や、「解説 インサイド .NET Framework [改訂版]
第4回 アセンブリとバージョン管理」
に詳しい説明が乗っているが、ODACの場合ODP.NETフォルダ配下にあるOracle.DataAccess.dllとODP.NET/PublisherPolicyフォルダ内のPolicy.x.xxx.Oracle.DataAccess.dllを登録してあげればアセンブリリダイレクトが定義される。具体的にはOraProvCfg.exeを用いて登録をすればよいのだが、その方法は別途記事を記している。
#アセンブリリダイレクトの問題
実際に、Policy.4.112.Oracle.DataAccess.configなどをエディタで開いてみてもらえればわかるが、Oracle.DataAccess.dlアセンブリリダイレクトは、古いバージョンのdllを参照していたアプリケーションに新しいバージョンのdllを使うよう指示されている。
現在ODACの18.0.0を手元に所持してるが、ここには(CLR4.0では)11.2以降の全てのOracle.DataAccess.dllを参照しているアプリケーションは4.122.18.3のバージョンを使うように書かれている。
ここで注意したいのは、参照しているdllよりも古いバージョンのdllを使うような記述が書かれていない点である。
つまり、4.122.18.3のバージョンを参照して作成されたアプリケーションは、より古いバージョンのODACがインストールされた環境では動かなくなってしまうということだ。
サイトから最新版のODACをダウンロードしてきてインストールをした場合、このようなケースに陥る可能性が高い。
#解決策
アプリケーションが動かなくなることを避けるためには、以下のような対策を考える必要がある。
ひとつ目の解決策は、アプリケーションをインストールするサーバーのODACを最新版にすることだ。
発行者ポリシーが謳っている通り、Oracle.DataAccess.dllは後方互換性があるので、古いバージョンをアンインストールし、互換性のある最新のODACをインストールしてもらえれば問題は解決する。
ふたつ目は、開発環境で参照するdllのバージョンを一番古いバージョンに設定する方法だ。
VSの設定で参照するOracle.DataAccess.dllを古いものに設定すればGAC参照時には新しいdllにリダイレクトされるので、どのバージョンのOracleに対しても接続が保障されている。
なお、ODACは複数バージョンを一つのPCにインストールすることも可能なので、インストールした中から必要なdllを選んで参照してあげればよいのだが、複数バージョンをインストールする際には環境変数やレジストリの設定が自分の意図したとおりになっていない可能性があるため、注意が必要になるが、この問題に関しては別途ページを改めてまとめようと思う。