はじめに
今まではWindowsフォームアプリのプロジェクトにDbContextとエンティティ、Migrationフォルダを置いていたのですが、別のプロジェクトでも使うしクラスライブラリプロジェクトを作ってそっちに置いた方がいいのかな?と思って移動しました。
Add-Migration
しました。
エラーが出ました。
なんでやorz
環境
・VisualStudio 2022 Comunnity 17.12.3
・Windowsフォームアプリ(.NET8.0)
・Windowsフォームクラスライブラリ
原因分析
エラーメッセージはこんな感じです:
Unable to create a 'DbContext' of type 'MyContext'.
The exception 'Object reference not set to an instance of an object.' was thrown while attempting to create an instance.
For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
-Verbose
でログを詳しく見てみると、
Finding application service provider in assembly 'POSレジライブラリ'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
こんな風にあります。
EFCoreはAdd-Migration
するときにCreateHostBuilder
メソッドを呼び出すらしいのですが、それがなかったみたいです。
なら、winformsのプロジェクトで動いたのはなんでだろう?と思って-Verbose
で見てみました。
Microsoft.EntityFrameworkCore.Design.Internal.AppServiceProviderFactory.CreateFromHosting(String[] args) An error occurred while accessing the Microsoft.Extensions.Hosting services.
Continuing without the application service provider.
Error: The entry point exited without ever building an IHost.
No application service provider was found.
Using context 'MyContext'.
Finding design-time services referenced by assembly 'POSレジ会計'...
こちらもアプリケーションサービスプロバイダーを探している途中にエラーが発生していますが、そのまま次のステップに進んでいます。
GitHub Copilotに聞いてみると、CreateHostBuilder
メソッドはASP.NETのホスティング環境を構築するのに使われるのに対して、winformsはデスクトップで作動するためCreateHostBulider
メソッドは適していない、とのことらしいです。
そして、winformsではApplication.Run
でフォームを起動する、と言っていました。
あまりよくわかっていませんが、ASP.NETではProgram
クラスのCreateHostBuilder
メソッドを呼ぶ必要があるがwinformsではエントリーポイントから起動できるよ、みたいな感じでしょうか。
解決策
どうしてもクラスライブラリプロジェクトをスタートアッププロジェクトにしたいのであれば、Program
クラスとCreateHostBuilder
メソッドを追加すれば出来そうです。
私の場合はクラスライブラリにする必要性は薄かったのでwinformsプロジェクトをスタートアッププロジェクトにしました。
参考リンク
追記(2024.12.26)
やっぱりモデルクラスはクラスライブラリプロジェクトにあったほうが便利だなーと思ってCreateHostBulider
メソッドを書かないままAdd-Migration
を試したらなんか行けました。なんで…?
相変わらずこの文は出てたんですが、winformsプロジェクトでやった時と同じようにそのまま進んでました。
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Using context 'MyContext'.
Finding design-time services referenced by assembly 'POSレジライブラリ'...
Finding design-time services referenced by assembly 'POSレジライブラリ'...
No referenced design-time services were found.