もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
Moqというnugetパッケージを使っているのだが、 そのMoqのパッケージについて、条件を付けて、
- 通常時は、Moqを参照しない
- 条件付きコンパイルシンボルに特定の文字列を書いたときだけ、Moqを参照する
ということをしたい。
前提
- VisualStudio2022
- .NET6
- C#コンソールアプリで実験
- 2023/4月時点に実験実施
結論
上の「やりたいこと」で書いた内容については、
- 条件付きコンパイルシンボルにシンボルを書くのをやめて、
- Configuration(DEBUGとかReleaseとかのやつ)に、Moq用のコンフィグを追加して、
- ビルド時にConfigurationがそのMoq用のコンフィグだったら、
- Moqのnugetパッケージを参照する
というようにした。
やりかた/やれること
以下に、その結論に達するまでに調べた内容をメモしておく。
csprojは、最初に一回設定したらあとはめったにいじらないモノ、というイメージだったが、実はいろいろできることを知った。
Debugビルド時だけ、nugetパッケージをリンクする
Debugビルド時だけ、Moqのnugetパッケージを使い、Moq(ダミー)の動作をさせたいときなどに使う。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup > <PackageReference Condition="'$(Configuration)'=='DEBUG'" Include="Moq" Version="4.18.4" /> </ItemGroup> </Project>
csprojで使うプロパティを、ビルド時に文字列を出力してデバッグする
- 先頭の
Project
要素にInitialTargets="Test"
を入れて、 - 下記のように
<Target Name="Test">
と、<Message>
を入れる。
<Project Sdk="Microsoft.NET.Sdk" InitialTargets="Test"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <Target Name="Test"> <Message Text="Project File Name = $(MSBuildProjectFile)" Importance="High"/> <Message Text="Project Extension = $(MSBuildProjectExtension)" Importance="High"/> </Target> </Project>
要素内のconditionに、メソッドを使う
下記の例だと、「条件付きコンパイルシンボル」に「MySymbol」というのを定義しているかどうかをMessageで出している。
条件付きコンパイルシンボルというのはコレ↓のこと。
<Project Sdk="Microsoft.NET.Sdk" InitialTargets="Test"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <Configurations>Debug;Release</Configurations> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DefineConstants>MySymbol</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> <DefineConstants>MySymbol</DefineConstants> </PropertyGroup> <Target Name="Test"> <Message Text="Debug? = $(DefineConstants.Contains(`MySymbol`))" Importance="High" /> </Target> </Project>
DefineConstants
が文字列のプロパティだから、stringがもつContainsメソッドが使えるっぽい。
※最初、条件付きコンパイルシンボルに特定のシンボルを書いたときだけ、あるnugetパッケージを参照するようにしたい、と考えていたが、それよりも、上の方でやっているようにDebug
/Release
に加えてもうひとつConfigurationを作って、そのConditionの名前を、「Condition="'$(Configuration)'=='DEBUG2'"」 みたいな感じで判定してあげた方が見る人がわかりやすそう。(そういう設定があるのが目で見えるので。)
要素内のconditionに、メソッドを使う その2
下記の例では、正規表現を扱うRegex
クラスを、csprojの中で使う例が紹介されている。
※気力が切れたので未確認。いざそういうことしたくなったら調べてみる。
参考
csprojの中でつかう変数
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2022 https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2022
csprojで条件式を書く方法
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/msbuild-conditional-constructs?view=vs-2022
要素の一覧(ItemGroupとか)
SDKの要素?(TargetFrameworkとか)
https://learn.microsoft.com/ja-jp/dotnet/core/project-sdk/msbuild-props#framework-properties
csprojの条件分けの書き方、参考になりそう
https://atmarkit.itmedia.co.jp/fdotnet/special/msbuild02/msbuild02_02.html
csprojの要素を自前で作れるらしい
https://atmarkit.itmedia.co.jp/fdotnet/special/msbuild02/msbuild02_03.html
csprojの中でデバッグのために文字列を出力する
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/walkthrough-using-msbuild?view=vs-2022