1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C# アセンブリのバージョンの謎を調べる(1)

Last updated at Posted at 2021-04-03

C# の Assembly 周りを職業柄深く理解しないといけないのだけど、自分の理解はとっても浅いと最近感じてきたので、勉強することにした。
特に、次の分野を勉強したい

  • Assembly Versioning
  • Resolve assembly loads
  • Strong Name and Side by side execution
  • Load and unload Assembly

あたりは抑えておいた方がよさそう

Assembly Version

まずは基本的なバージョニングについてみておきたい。

自分のライブラリが参照するライブラリがあり、それが自分と同じライブラリを使っている場合、バージョンを参照先より高くする

自分が実験してみたのですが、下記のように、自分のライブラリがあり、それが、自分のライブラリの内部で使用している別のライブラリの一部として、Newtonsoft.Json
あり、自分のライブラリが参照しているプロジェクトでも、Newtonsoft.Json が存在するとします。自分のライブラリの中で、Newtonsoft.Json を使いたい場合は、
必ずそれら2つよりもバージョンを高くします。

image.png

例えば、内部参照しているライブラリのバージョンより低いバージョンを使った場合、内部参照をしているパッケージが、11.0.2 を使っているのに、
自分のライブラリで、9.0.1 を使うと、両方のライブラリが 9.0.1 になります。ただし、これは使えなさそうです。Detected package downgrade: Newtonsoft.Json from 11.0.2 to 9.0.1
というエラーが出てしまいます。

image.png

これは、外部参照先であっても同じです。

image.png

エラーがダブルになりました。外部参照先は、12.0.2 です。安全のためには、自分のライブラリで参照を持たないか、それらより高いバージョンを使えばよくなります。13.0.1 を参照してみると、
自分のライブラリの参照が13.0.1 になるのがわかるでしょう。もちろん依存先のライブラリにはバージョンの変化はありません。

image.png

削除すると、高いバージョンに合わせる感じになります。内部参照のバージョンと比べると、外部参照の方が高いバージョンなので、内部参照の
ライブラリのバージョンが高くなりました。

image.png

バージョンの数字の決定

今まで実験した通り、cscprojファイルにバージョンを書いていても、同じライブラリのバージョン上のものがあれば、バージョンが上がったりしているのが
わかったと思います。バージョン指定をしているのに何でとおもうかもしれません。みんながよく使っている指定は、最小バージョンを指定しているので、上がるのはありなのです。

    <PackageReference Include="Newtonsoft.Json" Version="11.0.2"/>

image.png 

試しに、最大で、9.0.3 の指定をしてみました。

    <PackageReference Include="Newtonsoft.Json" Version="(9.0.3]"/>

image.png

元々がルールに外れるのでさんざんな結果です。折角なので適切だけど最大値あるとかやってみます。

バージョン指定を試してみる

バージョン指定を試してみます。csproj ファイルを、次のように指定してみます。最小バージョンが9.0.1 11.0.01未満です。

Reference.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <Version>1.0.2</Version>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" version="[9.0.1, 11)" />
  </ItemGroup>
</Project>

このプロジェクトを pack して、LocalNuGet に配置した後、11以上のバージョンを指定してみます。

AssemblyVersion.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
    <Version>1.0.1</Version>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
    <PackageReference Include="Referenced" Version="1.0.2" />
  </ItemGroup>

  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

image.png

NU1608 のワーニングなので、サプレスは出来そうですが、しっかり必要以上のバージョンアップを止めてくれました。

Severity	Code	Description	Project	File	Line	Suppression State
Warning	NU1608	Detected package version outside of dependency constraint: Referenced 1.0.2 requires Newtonsoft.Json (>= 9.0.1 && < 11.0.0) but version Newtonsoft.Json 12.0.2 was resolved.	AssemblyVersioning	C:\Users\tsushi\source\repos\AssemblyVersioning\AssemblyVersioning\AssemblyVersioning.csproj	1	

次回

次回はより高度な内容にする予定です。DLLのマニフェストの見かた、LoadAssemblyでロードしたときのバージョンコンフリクトの発生、
そして、LoadAssemblyしたときにDIコンテナを共有するとどのような挙動になるのか、というところをサンプルプログラムを作って
試してみたいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?