ネームスペースとディレクトリ構造

[S2.NET]フォルダの名前とか。

s2dotnet風フォルダ階層

.NETで大きめのライブラリィ組んでいると一度は気になるのがネームスペースとディレクトリの対応ではないだろうか。
Javaを使っていて.NETを始めると最初はびっくりするのだが.NETのネームスペースはJavaのパッケージとは違いプラットホームのファイルシステムのディレクトリ構造とネームスペースの論理構造は一致している必要が無いのだ。


.NETのネームスペース"namespace A.B.C.D"と"namespace A.B.C.E"は以下のどのようなディレクトリ構造で実現されていても配置されるクラスやインタフェースのネームスペースに影響はない。(ソースコード内に書かれたネームスペース(namespace〜)に影響される)

  • 1
src
├─A
│ └─B
│    └─C
│       └─D
│       └─E
  • 2
src
├─A.B.C.D
├─A.B.C.E
  • 3
src
├─A.B.C
│     └─D
│     └─E
  • 4
src
├─A.B.C
│   └─A.B.C.D
│   └─A.B.C.E

ただしマニフェストに埋め込むリソースなどをソースコードと共に配置している場合は注意しなければならない。実は例として故意に追加しておいたのだが構造4のディレクトリに配置された埋めこみリソースはビルドされるとディレクトリの構造がリソース名にも反映されるのだ。

src
├─A.B
│   └─A.B.C.D
│   │       └─ App.ico
│   └─A.B.C.E
│            └─ config.xml

App.icoとconfig.xmlのビルドアクションを「埋めこまれたリソース」としてビルドするとアセンブリ内では以下のように埋めこまれてしまうのだ。

アセンブリマニフェストに埋めこまれたリソースをildasm.exe等で見たイメージ

.mresource public A.B.A.B.C.D.App1.ico
{
  // 
}
.mresource public A.B.A.B.C.E.config.xml
{
  // 
}

名前A.B.C.D.App.icoではApp1.icoマニフェストリソースへアクセスすることはできない。

ネームスペースの構造をリソースに正しく反映するためには、例えば以下のような構造にする必要がある。

src
├─A.B.C
│   └─D
│   │ └─ App.ico
│   └─E
│      └─ config.xml

普通であれば構造4の様にしてしまう人はいないでしょう。まあ、私はこのようにして失敗している経験があるので言及したわけです。