この夏休みは、久しぶりにプログラミングをやっている。
ワテの開発環境は以下の通り。
- 自作Windows10x64パソコン(詳細)
- Visual Studio 2017 Community 15.8.1
だ。
どんなプログラムを作っているのかと言うと、ASP.NET MVCでデータベースを操作して表示すると言う、わりと基本的なプログラムだ。その中ではEntity Frameworkのコードファースト機能も利用している。
ワテの場合、Entity Frameworkの全体像はまだ十分には理解出来ていないが、このコードファーストは便利なので良く使う。つまり、C#のソースコードで、自前のクラスを定義しておけば、そのクラス内にあるパブリックなメンバ変数を使ってデータベースのテーブルが全自動で生成出来る機能だ。メンバ変数の名前とデータ型を使ってテーブルのカラムが生成される。
クラスのメンバ変数を後から追加・削除などの変更をした場合には、Migration機能を実行すれば、データベースのテーブルにその変更を反映する事も出来る。とっても便利だ。
具体的には
- Enable-Migrations
- Add-Migration
- Update-Database
などのコマンドをバンバン使っている。
さて、そのASP.NET MVCプロジェクトの開発において、些細な問題だが一つバグ(かな?)を発見したので、備忘録としてメモしておく事にした。
では、本題に入ろう。
Visual Studioではプロジェクト参照が便利
まずは参照設定をご存じない人の為に、簡単に説明しよう。
あくまでワテの理解なので、正式な説明はマイクロソフト社の公式サイトなどを参考にして頂きたい。
参照設定とは何か?
例えばC#でWindowsフォームアプリを開発するとしよう。
プロジェクトの名前は、WinFormPJとしておこう。
まあ、コンソールアプリでも何でも良いのだが。
そのWindowsフォームアプリを開発していて、各種の関数やクラスを作成したとする。
汎用性の高い関数は今後他のプロジェクトでも再利用したいので、別のC#クラスプロジェクトを作ってそちらに移植する事にする。
そのC#クラスプロジェクトの名前は、CSharpLibPJとしておこう。
さて、WinFormPJからCSharpLibPJの中にある関数を呼び出す為に必要な作業が参照設定だ。
要するに、プロジェクトAから他のプロジェクトBの中にある、パブリックなクラスや関数(メソッドと言うのが今風なのかな)を利用するための手法だ。
参照設定のやり方
参照設定のやり方は幾つかある。
今の場合は、WinFormPJもCSharpLibPJも自分で作っているプロジェクトなのでC#のソースコードもある。
そう言う場合には、プロジェクト参照と言うのをやれば良い。
一方、例えばネットから入手したDLLの中にある関数を呼び出したい場合もある。
ソースコードは無くて、コンパイル済のDLLしか無い場合だ。
そう言う場合はアセンブリ参照と言うのをやれば良い。
ここでは、プロジェクト参照のやり方を紹介しよう。
前提としては、これらの二つのプロジェクトはVisual Studioの一つのソリューションの中に追加されているとする。
プロジェクト参照のやり方
そのソリューションを開く。
そうすると二つのプロジェクトWinFormPJ、CSharpLibPJがソリューションエクスプローラーに表示されている。
今の場合は、WinFormPJからCSharpLibPJの関数をコールしたいので、WinFormPJ側で参照の設定を行う。
まず、ソリューションエクスプローラーにあるWinFormPJプロジェクトを展開して、その中にある[参照]と言う文字で右クリックすると
「参照の追加」
と言うメニューがあるので開く。
「参照マネージャ-」と言う画面が開く。
その右側にあるメニューから「プロジェクト」を選ぶと今開いているソリューションの中にあるプロジェクトの一覧が表示される。
今の場合は、CSharpLibPJが一つ表示される。
そのCSharpLibPJにチェックボックスがあるのでチェックを入れて[OK]をクリックすればプロジェクト参照の設定は完了だ。
参照設定が完了すればあとは開発に専念すれば良い
このようにプロジェクト参照の設定を行うと、WinFormPJプロジェクトのビルドの依存関係も自動で設定されて、CSharpLibPJを先にビルドした後でWinFormPJがビルドされる。
後は、WinFormPJの開発に専念すれば良い。
そこで作った関数が汎用性が高ければ、CSharpLibPJに移植すれば良い。
そのCSharpLibPJに移植した関数をWinFormPJから呼び出したい場合には、WinFormPJにおいて、そのC#ソースファイルの先頭で、
@using CSharpLibPJ;
の設定を追加すれば良い。
なお、CSharpLibPJプロジェクトの名前空間もCSharpLibPJと仮定している。
つまり、usingの後に記述するのは、参照したいプロジェクトの名前空間(Namespace)だ。
あとはWinFormPJのC#ソースファイルの中で、CSharpLibPJにあるpublicな関数やクラスなどのオブジェクトを自由に利用出来る。
これがプロジェクト参照のやり方と使い方の基本だ。
参照設定はコンソールプロジェクトやWindowsFormプロジェクトに対しても可能
ちなみに今の場合は、
- WinFormPJ C#ウインドウフォームアプリ
- CSharpLibPJ C#クラスライブラリ
でプロジェクトを作成したと仮定している。
ところが、プロジェクト参照はクラスライブラリ以外のプロジェクトに対して設定する事も可能だ。
- WinFormPJ C#ウインドウフォームアプリ
- CSharpLibPJ C#コンソールアプリ
などでも可能だ。
あるいは
- WinFormPJ C#ウインドウフォームアプリ
- CSharpLibPJ C#ウインドウフォームアプリ
でも可能だ。
さて、ここまでがVisual Studioにおけるプロジェクト参照のやり方の紹介であるが、いよいよワテが経験した問題を紹介したい。
まあ、そんなのに興味ある人は日本に数名しかいないかも知れないが。
ASP.NET MVCプロジェクトからC#コンソールアプリにプロジェクト参照した場合の問題
ワテの場合は、この夏休みに、
Visual Studio Community 2017 15.8.1
.NET Framework 4.7
の環境で、
- TopSecretMVCPJ C#ASP.NET MVCアプリ
- CSharpLibPJ C#コンソールアプリ
を開発している。
どんな物凄い秘密のプロジェクトかは、絶対に教えられない。
なぜなら、未完成だからだ。
さて、そんな事はどうでも良いが、この場合でもTopSecretMVCPJからCSharpLibPJへプロジェクト参照を設定する事は出来る。
かつ、上で説明したようにusingで名前空間を読み込めば、TopSecretMVCPJからCSharpLibPJの中のpublicな関数やクラスを利用出来る点は問題無く出来るのだ。
ところが、謎の問題に悩まされた。
cshtmlファイルの中で@using CSharpLibPJがエラーする
上で説明したプロジェクト参照を設定して、あとはTopSecretMVCPJプロジェクトの中のC#ソースファイルで
@using CSharpLibPJ;
すれば問題なくTopSecretMVCPJプロジェクトからCSharpLibPJプロジェクトのパブリックなクラスや関数などのオブジェクトにアクセス出来る。ビルドも正常に行える。
一方、TopSecretMVCPJプロジェクトの中のcshtmlファイルでもCSharpLibPJプロジェクトのパブリックなクラスを利用したい場合がある。
その場合も、上で示したC#ソースファイルでの記述とほぼ同じ文法で書けば良い。
@using CSharpLibPJ
注意事項としては、cshtmlファイル内で@usingを使う場合は名前空間の後に付ける末尾のセミコロンは不要だ。
このようにしてビルドすると正常に完了する。
ところがこのASP.NET MVCプロジェクト(TopSecretMVCPJ)を実行してindex.cshtmlをブラウザーで表示しようとすると、以下のエラーが出るのだ。
‘/TopSecretMVCPJ’ アプリケーションでサーバー エラーが発生しました。
コンパイル エラー
説明: この要求を送信するために必要なリソースをコンパイル中に、エラーが発生しました。以下のエラーの詳細を確認して、ソース コードを修正してください。コンパイル エラー メッセージ: CS0246: The type or namespace name ‘CSharpLibPJ’ could not be found (are you missing a using directive or an assembly reference?)
ソース エラー:
行 95:
行 96: @using CSharpLibPJ
行 97:
原因が分からん。
今まではこんなエラー経験した事は無い。
数十分試行錯誤して、ふと気づいた。
今回プロジェクト参照しているのはC#コンソールアプリだ。
今まではC#クラスライブラリプロジェクトにプロジェクト参照をするのは何度もやったが、C#コンソールアプリへのプロジェクト参照は過去に数回やった程度。
それもWinFormPJからだったかなと思う。
ASP.NET MVCプロジェクトからC#のコンソールアプリへプロジェクト参照したのは初めてかな?
逆だったら何度か経験がある。つまり、
C#のコンソールアプリのプロジェクトからASP.NET MVCプロジェクトへプロジェクト参照だ。これで問題に遭遇した事は無い。
で、兎に角、ASP.NET MVCプロジェクトからC#のコンソールアプリへプロジェクト参照したのが問題なのかなあと思って、C#のコンソールアプリをC#のクラスライブラリに変更してみた。
プロジェクト出力の種類変更方法
変更の仕方はCSharpLibPJプロジェクトのプロパティを開いて、
出力の種類
と言う項目のプルダウンメニューを開いて、
- Windowsアプリケーション
- コンソールアプリケーション
- クラスライブラリ
の中からクラスライブラリを選べばよい。
それでASP.NET MVCのプロジェクトTopSecretMVCPJをリビルドして表示してみたら、無事に表示出来た。
と言う事で無事に解決。
ただし、本来はCSharpLibPJはコンソールアプリにしたいので、TopSecretMVCPJをビルドして発行する場合には一時的にCSharpLibPJをクラスライブラリに変更しなくてはならない。
ちょと煩わしい。
まとめ
この記事では、Visual Studioの環境でプロジェクト参照についてワテ流に解説した。
プロジェクト参照の意味
プロジェクト参照のやり方
などを理解して頂いたと思う。
そんな中で、ASP.NET MVCプロジェクトからC#コンソールアプリプロジェクトにプロジェクト参照をしたら正常に参照設定出来るし、ビルドもエラー無しで完了する。
ところがそのASP.NET MVCプロジェクトを実行し表示すると、参照設定したプロジェクトが見つからないと言うエラーが出る。
原因は不明だ。
多分、Visual Studio 2017 15.8.1のバグだと思う。
あるいは、ワテが何か大きな勘違いをしている可能性もある。
まさに頓珍漢!
もし解決方法をご存じの方がおられましたら、教えて下さい。
コメント