Visual Basic 初級講座 [改訂版] |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Visual Basic 中学校 > 初級講座[改訂版] >
2021/5/2
この記事が対象とする製品・バージョン
![]() |
Visual Basic 2019 | ◎ | 対象です。 |
![]() |
Visual Basic 2017 | ◎ | 対象です。 |
![]() |
Visual Basic 2015 | ○ | 対象ですが、画面や操作が大きく異なる場合があります。 |
![]() |
Visual Basic 2013 | ○ | 対象ですが、画面や操作が大きく異なる場合があります。 |
![]() |
Visual Basic 2012 | △ | 対象外ですが、考え方は参考になります。 |
![]() |
Visual Basic 2010 | △ | 対象外ですが、考え方は参考になります。 |
![]() |
Visual Basic 2008 | △ | 対象外ですが、考え方は参考になります。 |
![]() |
Visual Basic 2005 | △ | 対象外ですが、考え方は参考になります。 |
![]() |
Visual Basic.NET 2003 | △ | 対象外ですがdll参照の説明は参考になります。 |
![]() |
Visual Basic.NET (2002) | △ | 対象外ですがdll参照の説明は参考になります。 |
![]() |
Visual Basic 6.0 | × | 対象外です。 |
目次
いろいろなプロジェクトや、他の人と機能を共有する最適な方法は パッケージ を使うことです。
以前(2010年ごろ?)はクラスライブラリをコンパイルして作成される dllファイルを使って共有する方法もよく使われていました。これを「dllの参照」や「dll参照」と呼びます。現在(2021年)でも、dll参照で機能を共有することはできますが、お勧めの方法ではありません。dll参照だと配布や依存関係の管理が面倒なため今ではパッケージを使う方法が主流になっています。
今回はまず、お勧めではない dllファイルを参照して共有する方法を説明し、問題点を明らかにします。
そのうえで、クラスライブラリをパッケージにして、実際に他のプロジェクトから呼び出してみて、問題点がいかに改善されているかを説明します。
機能の共有方法には、パッケージとdll参照の他にもプロジェクト参照という方法 と 共有プロジェクト という方法もあります。プロジェクト参照についてはは 初級講座 第31回 でクラスライブラリを説明した時に一緒に説明しています。共有プロジェクトについては説明しておらず、取り上げる予定はありませんが、ここでこの4つを簡単に表にまとめておきます。
機能の共有方法 | どういうときに使う? | 使用できる条件は? |
---|---|---|
共有プロジェクト | 同じソースコードをいろいろなプロジェクトに組み込みたい場合 | 共有したい機能のソースコードがある |
プロジェクト参照 | クラスライブラリの開発する場合 | クラスライブラリのソースコードがある |
dll ファイルを参照 | (まず使いません。以前使われていた方式です。) | dll ファイルがある |
パッケージをインストール | 自分のプログラムから共通機能を呼び出したい場合 | パッケージが公開されている |
共有プロジェクトとプロジェクト参照は、共通機能のソースコードがある場合に選択肢になるのに対し、dllファイルの参照とパッケージはソースコードがない場合に使用する手段で、ここに大きな違いがあります。
チームのメンバー全員でソースコードを共有して、修正や機能追加、デバッグなどを行う可能性があるのであれば、選択すべきは共有プロジェクトかプロジェクト参照です。
そうではなく、もう完成した機能を呼び出したい場合や、完全に分かれている別チームが作っている機能を呼び出したい場合などに選択すべきなのはパッケージです。(かつては dll参照でした。)
パッケージを使用するには、NuGet (ニューゲット) というツールを使用します。NuGet は Visual Studio 2013頃から、Visual Studioにはじめから組み込まれており簡単に使用することができます。
このツールを使うと世界中で公開されているパッケージを簡単にプロジェクトに組み込むのによく利用されますが、個人的なパッケージや、チーム内、会社内など限定的な範囲で使用することもできます。もっとも簡単な共有方法は、どこかのフォルダーにパッケージを入れて置き、その場所をNuGetから見に行くことです。このようにすることで、完全に組織内の閉ざされた環境でパッケージを共有するということも可能です。今回はその方法も説明します。
それでは dll参照を使って機能を共有する方式から説明します。
前述したようにお勧めな方法ではありませんが、単純なケースでは特に不便はなく、簡単に試すことができます。(問題がある例はこの後で説明します。)
実際にやってみましょう。
Visual Studio で 新しいクラスライブラリのプロジェクトを作成してください。
Visual Studioのバージョンによって画面や表示が異なります。Visual Studio 2019 (16.9.3)の場合、上記の「クラスライブラリ」を選択してください。「.NET Framework」とついている方は古いので選択しないでください。
プロジェクトの名前は Humans としておきます。
フレームワークには .NET 5 を使用します。
この記事ではプロジェクト名とフレームワークが重要なので、実際に試してみる場合にはできるだけ合わせておいてください。(※この記事が古くなって、.NET 6 や .NET 7 …が登場しているならば .NET 6, 7 を選択してもよいです。)
このHumansプロジェクトには、ダミーの人物検索機能をプログラムしてみます。
はじめからプロジェクトに含まれている Class1.vb の名前を変更して HumanSearch.vb にします。
次のように人物名を受け取り結果を返すクラスをメソッドをプログラムします。
ここでは検索結果は固定値で適当なものを返すことにします。
Public Class HumanSearch
''' <summary>
''' 人物を検索します。
''' </summary>
Public Function Search(name As String) As String
Return $"{name} は見つかりませんでした。"
End Function
End Class
VB2013の場合、$付きの文字列は作成できないので、Return name & " は見つかりませんでした。" としておいてください。
これでうまく動くか一度実行してみたいところですが、クラスライブラリプロジェクトなので実行できません。
実際の開発現場ではテストプロジェクトという種類のプロジェクトを別途作成して、クラスライブラリがうまく動くかテストしながら開発しますが、今回は割愛します。
このまま、Visual Studioの[ビルド]メニューから「ソリューションのビルド」を選択してください。
うまくいくと、出力ウィンドウに 「1 正常終了」と表示され、dllファイルが作成されます。
dllファイルの場所もすぐ上に表示されていますね。この dll を渡すことで人物検索機能を他の人と共有できます。物検索機能がほしい人にこのdllを渡せばよいのです。
今回は、一人二役で、他の人から dll を受け取ったつもりになって、この Humans.dll を C:\temp フォルダーにコピーしてください。このフォルダーがなければ作成してください。
後の説明でこのフォルダーを使用するので、できるだけパスを合わせておいてください。
それでは、実際に他のプロジェクトからこのdllの中にある人物検索機能を呼び出してみましょう。
今、Visual Studioを開いている場合は1度閉じてください。(閉じなくてもよいのですが紛らわしいので)
改めてVisual Studio を開いて、今度は WPF アプリケーション を新規作成してみましょう。プロジェクト名は何でもよいですフレームワークはクラスライブラリと同じもの(たとえば、 .NET 5)にしてください。
WPF アプリは初級講座ではほぼ初登場です。
Windowsフォームアプリケーションでも、コンソールアプリケーションでも構わないのですが、せっかくなので幅広く体験していただきたく、あえて、今まで説明していないWPFアプリをここで使ってみることにします。
WPFアプリケーションはWindowsフォームアプリケーションと同じように画面として動作するアプリケーションです。Windowsフォームアプリケーションより新しく、グラフィックスに強いのが特徴です。いろいろ便利なのですが、初心者には少し扱いが難しいというのが最大の難点です。
WPFアプリを作成すると画面を作るデザイン画面が表示されるので、ツールボックスを使ってここにボタンを1つ配置してください。ボタンを配置したらダブルクリックしてクリック時のプログラムを自動生成させます。この点はWindowsフォームアプリと同じですが、やってみるといろいろ違いがあることに気が付くと思います。
ボタンのプログラムは次の通りにしてください。
Class MainWindow
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
Dim searcher As New Humans.HumanSearch
Dim result As String = searcher.Search("聖徳太子")
MessageBox.Show(result)
End Sub
End Class
※ご存じかと思いますが、聖徳太子とは厩戸王のことです。念のため。→ 学校で扱い(Wikipedia)
この段階では、このWPFプロジェクトでは、Humansに参照設定をしていないので、このプログラムはエラーで実行できません。
次の手順でHumansを使用できるようにします。
まず、ソリューションエクスプローラーでプロジェクトを右クリックして、[追加] - [プロジェクト参照] をクリックしてください。
参照マネージャーというダイアログが表示されるので、右下の「参照」ボタンをクリックします。
ファイル名を選択するダイアログが表示されるので、前の手順でコピーした C:\tempフォルダーにある Humans.dll を選択して、「追加」をクリックします。
そして、Humans.dll がチェックされていることを確認して、「OK」をクリックしてダイアログを閉じます。
これで、この図のように WPFプロジェクトは C:\tempにある Humans.dll を参照する状態になりました。
プログラムのエラーは解消されて、実行できるようになっているはずです。
実行すると、ちゃんとクラスライブラリが返しているメッセージが表示されます。いいですね。
このようにして一度 dll を作成してしまえば呼び出すのは簡単だということが理解していただけたことと思います。
Visual Studio 2019 で .NET Core/.NET 5以降の場合、プロジェクトが現在参照しているものは、ソリューションエクスプローラーの依存関係のアセンブリに表示されます。
この Humans をクリックすると、プロパティウィンドウに C:\temp\Humans.dll というようにパスも表示されます。
参照を解除して元の状態に戻すには、Humansを選択した状態で Delete キーを押すか、右クリックして、削除を選択します。
なお、1度参照したファイルは最近使用したファイルに表示されるので次回からは楽に選択できます。
ここまで説明したようなとてもシンプルな勉強用の例では dllの参照には特に不便は感じません。
少し本格的なことをやりだすと途端に面倒になります。
ダミーの検索機能を改造して、少しはまともな検索機能にしてみましょう。
もう1度 クラスライブラリの Humansプロジェクトを開いてください。
歴史情報を取得できる Umayadia.Database.HistoricalTimeline というパッケージの機能を利用しましょう。
まず、ソリューションエクスプローラーで Humans プロジェクトを右クリックして、「NuGet パッケージの管理」をクリックしてください。(ソリューションではなく、プロジェクトを右クリックするように注意してください。)
参照をクリックして、検索欄に「Umyadia」と入力して Enter を押します。
そうすると、検索結果に Umayadia.Database.HistoricalTimeline が表示されるのでクリックして、右側に表示される「インストール」ボタンを押します。
この「インストール」とはパソコンに何かソフトウェアを入れるという意味ではなく、このプロジェクトにこのパッケージを組み込むという意味です。このプロジェクト以外には影響しません。
インストールは数秒で完了します。インストールされたか確認したい場合は、「インストール済み」をクリックして Umayadia.Database.HistoricalTimeline が表示されるか確認します。
次に このパッケージの機能を使って検索機能を強化します。
このパッケージを使うと歴史情報を取得できるので、情報の中から人物を検索するようにプログラムを次のように改造します。
Imports Umayadia.Database.HistoricalTimeline
Public Class HumanSearch
''' <summary>
''' 人物を検索します。
''' </summary>
Public Function Search(name As String) As String
Dim chronicle As New TimeLine
For Each ev As HistoricalEvent In chronicle.HistoricalEvents
If ev.title.Contains(name) Then
Return $"{ev.eventDate} {ev.title}"
End If
Next
Return $"{name} は見つかりませんでした。"
End Function
End Class
VB2013の場合、$付きの文字列は使用できませんので & で結合する形に変更してください。
最後に、Visual Studioの[ビルド]メニューから「ソリューションのビルド」を選択して、新しいバージョンの Humans.dll を作成します。
これを C:\temp にコピーしてWPFプロジェクトから呼び出してみましょう。
WPFプロジェクトを開いて、[ビルド]メニューの[ソリューションのリビルド]をクリックしてください。
参照したdllはプロジェクトのフォルダーにコピーされており、C:\tempのdllを置き換えただけでは自動的に置き換わりません。リビルドを実行することでこういった情報がリフレッシュされます。
この状態で実行すると、Umayadia.Database.HistoricalTimeline が見つからないというエラーが発生します。
Humans.dll が Umayadia.Database.HistoricalTimeline パッケージの機能を利用しているので、Humans.dll だけでは実行できない状態になってしまったというわけです。
これがdll参照の問題の1つです。参照しようとしているdllが他の何かに依存している場合(※これを「依存関係がある」と表現します)、依存している何かを解決しなくてはいけないのです。
この依存関係を解決する一般的な手段は2つあります。
1つは、WPFプロジェクト側でも Umayadia.Database.HitoricalTimelineパッケージをインストール方法です。
でも、この方法は考えものです。大きなシステムになってくるといろいろなプロジェクトやパッケージを使用するので、この調子だと実行するだけでも苦労するようになってしまいます。10個の依存関係を持つdllを参照する場合のことを考えてみてください。準備するだけでも面倒ですし、しばらくして、そのうちの1つか2つに重大なセキュリティ問題が発覚したのでバージョンアップしろというアナウンスが発表されるかもしれません。こんなことであなたの貴重な時間が浪費されて行ってしまいます。(依存関係を勝手にバージョンアップしたら、本体のdllの方がエラーになったり、依存関係同士の組み合わせを考慮したり…うんざりしますね)
もう1つのもっと良い方法が、Humansをパッケージにする方法です。
こちらは良いアイディアです。パッケージにしてしまうと必要な依存関係はVisual Studioが自動的に面倒を見てくれるようになるからです。
次のステップでは、dll参照ではなく、パッケージを使ってどうやってこの問題を解決するか見てみましょう。
クラスライブラリをパッケージにするのはとても簡単です。ソリューションエクスプローラーでプロジェクトを右クリックして「パック」を選択するだけです。
早速Humans を右クリックして、「パック」を選択してください。
作成されたパッケージの場所は、出力ウィンドウに表示されます。
パッケージの拡張子は nupkg です。バージョン番号もついて、Humans.1.0.0.nupkg というファイルが作成されます。
この nupkg ファイルの実体は zip ファイルです。拡張子を zip に変更して中を確認することもできます。
パッケージを呼び出す場合は dll とは違いnupkgファイルを直接参照することはできません。
「パッケージソース」と呼ばれる場所を用意して、そこにパッケージを置いておきます。Visual Studioはパッケージソースから必要なパッケージを探し出してプロジェクトにインストールします。
パッケージソースとしては nuget.org と大規模な世界共有のサイトがはじめから登録されており、20万個以上のパッケージが登録されています。世界中に公開したい場合はこのnuget.orgにパッケージをアップロードすることになります。さきほど使用した Umayadia.Database.HistoricalTimeline も、私が nuget.org にアップロードしておいたものです。NuGetを使って簡単にインストールできましたよね。
しかし、今回のようにちょっとした練習をいちいち世界中に公開するのは気が引けますし、チーム内や会社内だけで共有したいパッケージもあるはずです。そんな場合は独自のパッケージソースを準備します。
といっても、フォルダーを用意するだけで簡単にできます。
今回は試しに C:\temp\package というフォルダーを作成して、さきほど作成した Humans.1.0.0.nupkg をコピーしておいてください。
WPFプロジェクトを開いていなければ開いてください。既に開いていればそのまま操作を続けて結構です。
Visual Studio からこのフォルダーをパッケージソースとして認識させるために [ツール]メニューの[オプション]から、[NuGet パッケージ マネージャー] - [パッケージ ソース]をクリックし、右上の緑の + ボタンをクリックします。
新しい項目が追加されるので、名前には好きな文字を入れましょう。たとえば、「Local Folder」としておきます。
ソースには、右の ... ボタンをクリックして、C:\temp\package フォルダーを選択します。
そして、「更新」ボタンをクリックします。
以上で、Visual Studioは C:\temp\package フォルダーをパッケージソースと認識し、この中にあるパッケージを扱えるようになります。
この設定ではVisual Studioで共通であり、今後新しいプロジェクトを作成したり開いたりしても反映されています。
それでは WPFプロジェクトでこのパッケージソースから Humans パッケージをインストールしてみましょう。
まず、紛らわしいので dll 参照を削除してください。
それには、ソリューションエクスプローラーで依存関係から、Humans を選択し、右クリックから削除ををクリックします。
次に、ソリューションエクスプローラーで WPFプロジェクトを右クリックして、「NuGet パッケージの管理」をクリックしてください。(繰り返しになりますがソリューションではなく、プロジェクトを右クリックするように注意してください。)
そして、右上にあるパッケージソースで 先ほど追加した Local Folder を選択します。
この状態で、左上の参照をクリックすると、Humans が表示されます。
もし、C:\temp\pacakge フォルダーに他にもパッケージを配置していれば表示されます。
Humansをクリックして、右側のインストールをクリックすることで、このプロジェクトに Humans を組み込めます。
そして、ここがパッケージに素晴らしいところなのですが、この Humans を呼び出すには、 Umayadia.Database.HistoricalTimeline も必要であるということを Visual Studio が自動的に検知します。なので、このパッケージも一緒にインストールしますよという確認を出してくれます。
プログラマーはここで OK をクリックするだけです。
この機能のおかげでかなり複雑な参照関係でもプログラマーは OK を押すだけで簡単にパッケージを利用できます。
(これがなかった時代は、必要な機能を探してそれぞれダウンロードして組み込むなどかなり面倒な場合もありました。)
インストール後は、このように依存関係のパッケージの項目で Humans と Humans の実行に必要な Umayadia.Database.HistoricalTimeline が表示されます。
これで WPFプロジェクトを実行できるようになります。
実行してボタンをクリックしてみましょう。次のように表示されれば成功です。
593 聖徳太子が摂政になる
Umayadia.Database.HistoricalTimelineから歴史データを取得し、Humansが聖徳太子を検索して、ヒットした情報をWPFプロジェクトが表示しているというわけです。
ちなみにこのUmayadia.Database.HistoricalTimeline の歴史データは古代日本の情報だけインプットしており、量も少ないです。「卑弥呼」や「蘇我馬子」、「推古天皇」、「大伴金村」はヒットしますが、「源頼朝」や「徳川家康」などはヒットしません。