VB のたまご

作成日: 2017/08/13, 更新日: 2017/08/15


.NET Core で、ソリューションファイルを含めた、複数プロジェクトの作成方法


1.プロジェクト参照

  •  ここでのソリューション構成は以下の通りです。ソリューション直下に2つのプロジェクトが管理されていて、 vbapp1 プロジェクトが、vblib1 プロジェクトを、プロジェクト参照している状態です。
  • sln
      + vbapp1 ★←vblib1.dll をプロジェクト参照している
      + vblib1
    

  •  まずは、ソリューションファイルを配置するフォルダを作成します。
  • $ mkdir vbapp1
    $ cd vbapp1
    

  •  ソリューションファイルを作成します。
  • $ dotnet new sln
    

  •  プロジェクトを作ります。コンソールアプリケーションとクラスライブラリの2つ作ります。
  • $ dotnet new Console -lang VB -o vbapp1
    $ dotnet new ClassLib -lang VB -o vblib1
    

  •  ソリューションファイルに、2つのプロジェクトを登録します。
  • $ dotnet sln add vbapp1/vbapp1.vbproj
    $ dotnet sln add vblib1/vblib1.vbproj
    

  •  vbapp1 プロジェクトに、vblib1 プロジェクトを登録します。
  • $ cd vbapp1
    $ dotnet add reference ../vblib1/vblib1.vbproj
    

  •  ソリューションファイルがあるフォルダに戻って、ビルドします。
  • $ cd ../
    $ dotnet build
    

  •  VSCode を起動します。引数として、ドットを入力することで、 このソリューション一式を開いた状態で起動することができます。
  • $ code .
    

  •  最初に、vblib1/Class1.vb からプログラムを作成していきます。 Class1.vb を開いて、以下のプログラムを入力します。

  •  Class1.vb
  • ' 名前空間は、vblib1.Class1
    Public Class Class1
    
        Public Function GetMessage() As String
            
            Return "Hello, vblib1.Class1 !"
            
        End Function
        
    End Class
    

  •  続いて、vbapp1/Program.vb を開いて、以下のプログラムを入力します。

  •  Program.vb
  • Imports System
    Imports vblib1
    
    Module Program
    
        Sub Main(args As String())
            
            Dim obj = New Class1
            Console.WriteLine(obj.GetMessage())
            
        End Sub
        
    End Module
    

  •  後はビルドするだけです。構成(launch.json)とタスクランナー(tasks.json)を「.NET Core」に設定します。

  •  launch.json に実行ファイルのパスを設定します。注意点としてこのテンプレートは、 【プロジェクトファイルを起点とした】実行ファイルまでのパスを記載しているので、現在の場所(ソリューションファイルがある場所)から見ると、 「netcoreapp2.0/xxx.dll」と変更しただけでは理解できません。プロジェクトフォルダのパスも含めて書き換えます。
  • "program": "${workspaceRoot}/vbapp1/bin/Debug/netcoreapp2.0/vbapp1.dll",
    

  •  tasks.json にはビルドコマンドを修正します。 このファイルは、開いた時に "dotnet" だけの場合と "dotnet build" と修正後の場合があり、よく分かっていません。
  • "command": "dotnet build",
    

  •  実行して、以下の文字列が表示されていれば OK です。
  • Hello, vblib1.Class1 !
    


2.NuGet による参照

  •  続いては、NuGet による参照です。今回は、json データを扱うことができる Newtonsoft.Json ライブラリを、 ダウンロードして参照します。json データは vblib2 プロジェクトで管理することにします。

  •  先ほどと同じ構成に加えて、クラスライブラリ側で NuGet する構成です。
  • sln
      + vbapp2 ★←vblib2.dll をプロジェクト参照している
      + vblib2 ★Nuget で、Newtonsoft.Json を参照している
    

  •  それでは、プロジェクト設定までやってしまいましょう。
  • $ mkdir vbapp2
    $ cd vbapp2
    $ dotnet new sln
    
    $ dotnet new Console -lang VB -o vbapp2
    $ dotnet new ClassLib -lang VB -o vblib2
    
    $ dotnet sln add vbapp2/vbapp2.vbproj
    $ dotnet sln add vblib2/vblib2.vbproj
    
    $ cd vbapp2
    $ dotnet add reference ../vblib2/vblib2.vbproj
    

  •  vblib2 プロジェクトファイルを編集します。
  • $ cd ../vblib2
    $ gedit vblib2.vbproj
    

  •  vblib2.vbproj
  • <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp2.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="Newtonsoft.Json">
          <Version>*</Version>
        </PackageReference>
      </ItemGroup>
    
    </Project>
    

  •  ItemGroup タグ内のまとまりを追加します。Version タグに「*」を設定すると最新バージョンを、 任意のバージョンを設定するとそのバージョンをダウンロードして組み込まれます。今回は最新バージョンです。

  •  保存したら、ソリューションファイルがあるフォルダに戻って、「dotnet restore」して関連するデータを取得します。
  • $ cd ../
    $ dotnet restore
    $ dotnet build
    

  •  VSCode を起動します。引数として、ドットを入力することで、 このソリューション一式を開いた状態で起動することができます。
  • $ code .
    

  •  最初に、vblib2/Class1.vb からプログラムを作成していきます。 Class1.vb を開いて、以下のプログラムを入力します。

  •  Class1.vb
  • Imports Newtonsoft.Json
    
    ' 名前空間は vblib2.Class1
    Public Class Class1
    
        Public Class Person
            Public Property Name As String = String.Empty
            Public Property Age As Integer = 0
        End Class
    
        Public Function GetJsonData() As String
    
            Dim p = New Person With
            {
                .Name = "taro",
                .Age = 20
            }
            Dim json = JsonConvert.SerializeObject(p, Formatting.Indented)
            Return json
    
        End Function
    
    End Class
    

  •  続いて、vbapp2/Program.vb を開いて、以下のプログラムを入力します。

  •  Program.vb
  • Imports System
    Imports vblib2
    
    Module Program
    
        Sub Main(args As String())
    
            Dim obj = New Class1
            Console.WriteLine(obj.GetJsonData())
    
        End Sub
    
    End Module
    

  •  後はビルドするだけです。構成(launch.json)とタスクランナー(tasks.json)を「.NET Core」に設定します。

  •  launch.json に実行ファイルのパスを設定します。注意点としてこのテンプレートは、 【プロジェクトファイルを起点とした】実行ファイルまでのパスを記載しているので、現在の場所(ソリューションファイルがある場所)から見ると、 「netcoreapp2.0/xxx.dll」と変更しただけでは理解できません。プロジェクトフォルダのパスも含めて書き換えます。
  • "program": "${workspaceRoot}/vbapp2/bin/Debug/netcoreapp2.0/vbapp2.dll",
    

  •  tasks.json にはビルドコマンドを修正します。 このファイルは、開いた時に "dotnet" だけの場合と "dotnet build" と修正後の場合があり、よく分かっていません。
  • "command": "dotnet build",
    

  •  実行して、以下の文字列が表示されていれば OK です。
  • {
      "Name": "taro",
      "Age": 20
    }
    


3.個別に作成した dll ファイルの直接参照

  •  続いては、個別に作成した dll ファイルの直接参照です。 vblib3 をビルドして vblib3.dll を作成。vbapp3 に vblib3.dll をコピペして、 プロジェクトファイルに直接参照するように記載します。該当するコマンドは無いので?手動で設定します。
  • sln
      + vbapp3 ★何も参照無し
      + vblib3  ★何も参照無し
    

  •  それでは、プロジェクト設定までやってしまいましょう。
  • $ mkdir vbapp3
    $ cd vbapp3
    $ dotnet new sln
    
    $ dotnet new Console -lang VB -o vbapp3
    $ dotnet new ClassLib -lang VB -o vblib3
    
    $ dotnet sln add vbapp3/vbapp3.vbproj
    $ dotnet sln add vblib3/vblib3.vbproj
    
    $ dotnet restore
    $ dotnet build
    

  •  ビルドが通ったら、vblib3/Class1.vb を作ります。 VSCode を起動して、Class1.vb を開いて以下を入力します。ドットを忘れないように注意してください。
  • $ code .
    

  •  Class1.vb
  • ' 名前空間は vblib3.Class1
    Public Class Class1
    
        Public Function GetMessage() As String
            Return "Hello, World from vblib3.Class1!"
        End Function
    
    End Class
    

  •  保存したら、【VSCode を閉じます】。そして、再度ビルドします。
  • $ dotnet build
    

  •  vblib3 フォルダ内に生成された dll ファイルを、vbapp3 フォルダにコピペします。 コピーコマンドでは、ドットの付け忘れに注意してください。
  • $ cd vbapp3
    $ cp ../vblib3/bin/Debug/netstandard2.0/vblib3.dll .
    $ ls
    

  •  コピー後、プロジェクトファイルを編集します。
  • $ gedit vbapp3.vbproj
    

  •  vbapp3.vbproj
  • <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.0</TargetFramework>
      </PropertyGroup>
      
      <ItemGroup>
        <Reference Include="vblib3">
          <HintPath>vblib3.dll</HintPath>
        </Reference>
      </ItemGroup>
    
    </Project>
    

  •  ItemGroup タグ一式を追加します。直接参照させたい場合は、HintPath タグを記載して参照します。

  •  VSCode を起動します。引数として、ドットを入力することで、 このソリューション一式を開いた状態で起動することができます。
  • $ cd ../
    $ code .
    

  •  呼び出し側を作成します。

  •  Program.vb
  • Imports System
    Imports vblib3
    
    Module Program
    
        Sub Main(args As String())
    
            Dim obj = New Class1
            Console.WriteLine(obj.GetMessage())
    
        End Sub
    
    End Module
    

  •  後はビルドするだけです。構成(launch.json)とタスクランナー(tasks.json)を「.NET Core」に設定します。

  •  launch.json に実行ファイルのパスを設定します。注意点としてこのテンプレートは、 【プロジェクトファイルを起点とした】実行ファイルまでのパスを記載しているので、現在の場所(ソリューションファイルがある場所)から見ると、 「netcoreapp2.0/xxx.dll」と変更しただけでは理解できません。プロジェクトフォルダのパスも含めて書き換えます。
  • "program": "${workspaceRoot}/vbapp3/bin/Debug/netcoreapp2.0/vbapp3.dll",
    

  •  tasks.json にはビルドコマンドを修正します。 このファイルは、開いた時に "dotnet" だけの場合と "dotnet build" と修正後の場合があり、よく分かっていません。
  • "command": "dotnet build",
    

  •  実行して、以下の文字列が表示されていれば OK です。
  • Hello, World from vblib3.Class1!
    


3その2.もしも、実行時エラーが出た場合


    ポップアップ画面が出て「残念ながら、Ubuntu 17.04 で内部エラーが発生しました。」、または「残念ながら、アプリケーションdotnetが予期せず停止しました。」と書かれていた。
    

  •  または、

  • $ cd vbapp3/
    $ dotnet run
    
    Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'vblib3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
    

  •  と表示された場合は、vbapp3 プロジェクトフォルダ内にある「bin」、「obj」フォルダを削除します。
  • $ rm -R bin
    $ rm -R obj
    

  •  さらに、念のため、vblib3.dll も消して、再度コピペするのもいいかもしれません。
  • $ rm vblib3.dll
    $ $ cp ../vblib3/bin/Debug/netstandard2.0/vblib3.dll .
    

  •  私の環境で出た実行時エラーですが、「bin」、「obj」フォルダを削除したらうまく実行できました。 (削除したら、もう一回ビルドし直すよ)。 プロジェクト作成時点で、空ビルドしたことが原因だったのかな?と動作的な現象から考えています。 ひとまず実行できて安心です(^_^.)。


まとめ

  •  ソリューション構成の複数プロジェクト管理ができるようになりました!やった!

  •  今更気づいたのですが、クラスライブラリの場合、TargetFramework タグの値が「netstandard2.0」になっていますね。 「netcoreapp2.0」で統一されているものと思っていたので、ちょっとびっくりしました。 間違って「netcoreapp2.0」に書き換えてしまってたし!まあ、このサンプルは Ubuntu 上で動けばいいだけなので・・・。

  •  プロジェクト単位に役割分担(レイヤー分割)することで、規模が大きいプログラムは見通しがしやすくなります。 そのため、ソリューション構成を作れることは大事な事ですよね。