Skip to content

MS_VSSolutionStructure

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

VSソリューション プロジェクトの構成検討

概要

Visual Studio の、「ソリューション」・「プロジェクト」の構成を検討する際の
ポイントについて説明する。

ソリューション・プロジェクト

Visual Studio では、開発するプログラムを、
ソリューション・プロジェクトという単位で管理する。

  • 1つのプログラムは、1-複数のアセンブリ(EXE や DLL ファイル)から
    構成される場合がある。

  • 1つの Web サイト・Web アプリケーションも、
    1-複数のアセンブリやコンテンツ ファイルから構成される。

  • また、各アセンブリをコンピュータにインストールするための
    「セットアップ プログラム」・「Web セットアップ プログラム」などがある。

補足(3 つの単位の対応関係): 混乱しやすいので先に整理する。

ソリューション(*.sln)      … 1 つ以上のプロジェクトを束ねる「作業単位」
  └ プロジェクト(*.csproj) … 1 つのアセンブリを作る「ビルド単位」
       └ アセンブリ(*.dll) … 1 つの「配置・バージョン管理単位」

原則 1 プロジェクト = 1 アセンブリであり、
ソリューションはビルドはするが、成果物そのものではない
.NETアセンブリ も併せて参照。

プロジェクト

  • プロジェクトのビルドに関する構成情報を保持している。
  • 1つのアセンブリを作成するには、1つの「プロジェクト」が必要になる。
  • 1つの基本的なプロジェクトは1つのアセンブリを出力する(EXE、DLL)。

プロジェクト ファイル

  • *.csproj(C# 用)、*.vbproj(VB 用)などの拡張子を持つ。

  • Windows アプリケーションの VB プロジェクトのプロパティの例

    • アプリケーション

      • アセンブリ名
      • 名前空間
      • アプリケーションの種類
      • アイコン
      • スタートアップ フォーム
      • フレームワーク
      • プロパティ
      • ,etc.
    • コンパイル

      • ビルド出力パス
      • 詳細コンパイル オプション
      • Option Explicit,Strict,Compare
      • 警告・エラーの表示
      • ,etc.
    • デバッグ
      デバッグ時の動作の設定をする。

      • スタートアップ
      • コマンドライン引数
      • ,etc.
    • 参照
      アセンブリや COM コンポーネントなど、
      プロジェクトで使用するコンポーネントの参照設定を設定する。

    • リソース
      プロジェクトのリソースを設定する。

      • 文字列
      • イメージ
      • アイコン
      • オーディオ
      • ファイル
      • ,etc.
    • 設定
      app.config のユーザ セッティング情報を設定する。

    • 署名
      アセンブリに厳密名などのアセンブリ署名をしたりする。

    • セキュリティ、発行
      ClickOnce アプリケーションで使用する設定をする。

補足: これらの設定は、いずれも MSBuild
プロパティとして .csproj に書かれる
GUI はその編集画面に過ぎない。
SDK 形式のプロジェクトでは .csproj が非常に短くなったため、
直接編集する方が速い場面も多い。

分割の意味

  • モジュール単位の変更
  • 配布単位の変更(アセンブリでの配布)

ソリューション

  • 全体のビルドに関する構成情報を保持している。

  • 複数のアセンブリから構成されるアプリケーションを作成できる。

  • このような構成を行う場合、以下の2通りの方法がある。

    • 複数のアセンブリをプロジェクトでまとめる(バイナリ参照)。
    • 複数のプロジェクトをソリューションでまとめる(プロジェクト参照)。

ソリューション ファイル

  • *.sln の拡張子を持つ。

  • ソリューションのプロパティの例

補足(最新化): .NET SDK 10 以降では、
*.slnx という新しい XML 形式のソリューション ファイルが導入された。
従来の .sln は独自形式で GUID が多く、
マージ コンフリクトが起きやすいという問題があったが、
.slnx はプロジェクトのパスを列挙するだけの素直な XML になっている。

<Solution>
  <Project Path="src/App/App.csproj" />
  <Project Path="src/Lib/Lib.csproj" />
</Solution>

分割の意味

  • ビルド単位の変更
  • 配布単位の変更(MSI での配布)

分割のメリット・デメリット

一般的に小規模開発の場合は分割を少なくして、大規模開発の場合に分割を検討する。

トレードオフ

メリット

  • 管理が容易になる。

  • 開発作業の分担が可能になる。

  • 部品化等により差し替えが容易になる。

  • 修正箇所毎、ビルド範囲を絞る事ができる。

  • アセンブリMSI での配布が容易。

  • プロセス、アプリケーション ドメイン分割により、
    障害範囲を少なくできる。

デメリット

  • 管理が煩雑になる。

  • 開発作業の分担ができなくなる。

  • 部品化等により差し替えができなくなる。

  • 修正箇所毎、ビルド範囲を絞る事ができなくなる。

  • 複数のアセンブリMSI
    組み合わせた配布が必要になる。

  • プロセス、アプリケーション ドメイン分割により、
    プロセス間通信が必要になる。

補足(この表の読み方): メリットとデメリットが
同じ項目の裏返しになっている点が要点である。
原文は「分割しない場合のデメリット」を並べているのではなく、
分割しすぎた場合のデメリットを並べていると読むのが正しい。

分割しない ◀──────────────────▶ 分割しすぎ
 ・ビルドが遅い                    ・管理が煩雑
 ・差し替えできない                ・参照関係が追えない
 ・分担しにくい                    ・ビルド順序が複雑

補足(実務上の目安): 現在の一般的な指針は
**「プロジェクトは少ないほど良い」**である。

  • プロジェクト数はビルド時間に直結する(1 プロジェクト = 1 コンパイル)
  • アセンブリ境界は実行時のコストでもある(型のロード、JIT)
  • 「レイヤごとにプロジェクトを分ける」だけでは設計上の意味が薄い
    (フォルダと internal で足りることが多い)

分けるべき明確な理由があるときにだけ分ける、というのが原則。

分ける理由
別々に配布する NuGet パッケージにする、他システムへ提供する
参照の向きを強制したい ドメイン層がインフラ層を参照しないことを保証する
ターゲットが違う 一方は netstandard2.0、他方は net8.0
テストプロジェクト 本体と一緒に配布しない

補足(最新化): アプリケーション ドメインは
.NET Core 以降存在しない
(作成できない)。
以下は .NET FrameworkIIS 前提の話である。

.NET Framework .NET(Core 系)
分離の単位 AppDomain(1 プロセス内で複数) プロセス
アセンブリのアンロード AppDomain 単位で可能 AssemblyLoadContext で可能
Web の分離 IIS のアプリケーション プール + AppDomain プロセス(Kestrel)単位

ASP.NET Core では 1 アプリ = 1 プロセスが基本であり、
分離はコンテナやアプリケーション プールの粒度で考えることになる。

異なるアプリケーション ドメインに画面遷移する方法

  • Server.Transfer は不可能。
  • Response.Redirect, Link などの Get メソッドは可能。
  • クロスページ ポストバックなどの POST メソッドは可能。

異なるアプリケーション ドメインと情報共有する方法

以下の状態管理技術は、異なるアプリケーション ドメインと情報共有できない。

  • Application オブジェクト

  • 静的変数

  • Cache オブジェクト

  • Session オブジェクト

  • その他

    • ViewState は同一 WebForm 画面内でのみ有用。
    • HttpContext は、Server.Transfer 画面遷移の間で有用

以下の状態管理技術は、異なるアプリケーション ドメインと情報共有できる。

  • QueryString
  • Cookie
  • Hidden
  • Cookie 認証チケット
    ASP.NET2.0 から ASP.NET の Forms 認証の認証チケットを
    • 複数のサイト間で共有する仕組みが用意され、
    • 複数のサイト間で利用できるようになった。

各状態管理技術については、コチラを参照。

補足(この分類の本質): 共有できるものとできないものの違いは、
どこに状態が置かれているかで決まる。

【共有できない】サーバのメモリ(プロセス内)に置く
   Application / 静的変数 / Cache / Session(InProc)

【共有できる】クライアントが持ち運ぶ
   QueryString / Cookie / Hidden / 認証チケット

したがって Session も「外に出せば」共有できる
SQL Server セッション ステート、Redis(分散キャッシュ)を
使えばプロセスをまたげる。
これは .NET CoreのDockerコンテナ化 で述べた
「コンテナは複数インスタンスに増えるので状態を外出しする」
という話とまったく同じ構図である。

参照設定の選択

プロジェクト参照

  • プロジェクトに対して参照設定を行う。

  • ビルド順も自動的に管理され、バージョンの不一致などが起こり難く使い易い。

  • 参照先のプロジェクトの変更・差し替えが容易なので、
    FIX していないモジュールに対してはプロジェクト参照を使用する。

バイナリ参照

  • アセンブリに対して参照設定を行う。

  • 参照先のバイナリの変更・差し替えが面倒なので、
    FIX したモジュールに対してはバイナリ参照を使用する。

補足(現在は 3 つ目の選択肢がある): 「FIX したかどうか」で
使い分けるという原文の整理は妥当だが、
現在は NuGetPackageReference
バイナリ参照の上位互換として使える。

方式 向く場面 依存の解決
プロジェクト参照 同じソリューション内。同時に開発する ビルド順が自動
バイナリ参照(HintPath) 手元の DLL を直接指す 手動(推移的依存も自分で)
PackageReference 別リリース サイクルの共通部品 自動(推移的依存も解決)

バイナリ参照は推移的依存を自分で管理する必要があるため、
現在は NuGet 化するのが素直である
(社内なら NuGet プライベート・リポジトリ)。

Web アプリケーション、Web サイト

関係

1 Web アプリ・サイト ≒ 1 IIS アプリ

  • 1つの Web アプリケーション・Web サイトは、
    1つの IIS のアプリケーションと対応する。
  • 複数の Web アプリケーション・Web サイトを
    1つの IIS のアプリケーションに纏めることはできない。

複数プロジェクトから1 Web アプリ・サイトを構成する方法

1つの Web アプリケーション・Web サイトを複数プロジェクトにまとめる方法

裏ワザ的な方法だと思いますが・・・、

補足(最新化): ASP.NET Core では
Razor クラス ライブラリ (RCL) により、
View やページ、静的ファイルを別プロジェクトに置いて合成できる
原文が「裏ワザ的」としていた構成が、標準機能になった。

WebApp.csproj      … ホスト
  └ 参照 Feature.A.csproj(RCL)… Views / wwwroot を含む
  └ 参照 Feature.B.csproj(RCL)

Web アプリ・サイト間で SessionCookie、Cookie 認証 Ticket を共有する方法(ASP.NET

上記のようにサイトを纏めなくても、SessionCookie、Cookie 認証 Ticket が共有できれば。

配置

  • Web サイトを本番環境に配置する方法には、

    • ファイル・フォルダのコピー
    • プリコンパイル後のファイル・フォルダのコピー
    • セットアップ プログラムによるインストール

    などがある。

  • Web アプリケーションを本番環境に配置する方法には、

    • 発行、Web Deploy
    • セットアップ プログラムによるインストール

    などがある。

ファイル・フォルダのコピー

  • アセンブリが生成されていない状態でアプリケーションを配布した際の
    初期要求時に JIT コンパイルが実行される。
  • JIT コンパイルによりアセンブリが生成され、その後にアプリケーションが実行される。
  • JIT コンパイルにより生成されたアセンブリは、
    %windir%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files で確認できる。

プリコンパイル後のファイル・フォルダのコピー

  • 事前コンパイルによりアセンブリを生成しておくことで
    初期要求時の JIT コンパイルを不要にできる。
  • この場合、Web サイトのファイル システム上にアセンブリが生成される。
  • プリコンパイルにより生成されたアセンブリは、
    生成された Web サイトのフォルダの直下にある「bin」フォルダで確認できる。

補足(Web サイトと Web アプリケーションの違い): この節が
2 つを分けて説明しているのは、プロジェクトの種類が違うためである。

Web サイト Web アプリケーション
プロジェクト ファイル 無い(フォルダがそのままプロジェクト) ある.csproj
コンパイル 実行時(初回要求時に JIT) ビルド時(1 つの DLL に)
配置 ソース(.aspx.cs)ごとコピー bin の DLL + .aspx

Web サイト形式はソース コードが本番に置かれるため、
セキュリティ・性能の両面で現在は使われない。
詳細は ASP.NETの構成(Webサイト・Webアプリ)を参照。

セットアップ プログラムによるインストール

Web セットアップ プログラムによる Web サイトのインストールが可能。

ASP.NET の配置(発行)


Tags: 移行, .NET開発

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally