Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
.NET Fringe Japan 2018新年会short talk
Search
Atsushi Eno
January 27, 2018
Technology
0
210
.NET Fringe Japan 2018新年会short talk
Atsushi Eno
January 27, 2018
Tweet
Share
More Decks by Atsushi Eno
See All by Atsushi Eno
[COSCUP2024] Catching up Trends in Audio App Development
atsushieno
0
390
Building Kotlin Multiplatform Libraries in 2024
atsushieno
0
3.3k
Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話
atsushieno
1
640
building_audio_plugin_ecosystem_on_Android.pdf
atsushieno
0
1.1k
get updated to the latest realtime audio processings knowledge base (2023) (再履修: 2023年までの リアルタイムオーディオ処理)
atsushieno
1
1.1k
learning how DAWs work, with Zrythm
atsushieno
0
1.1k
What for, Where and How to Adopt MIDI 2.0
atsushieno
0
1.2k
audio plugin format study meetup 2022.7.6 (JP)
atsushieno
0
1.6k
CLAPオーディオプラグイン is 何?
atsushieno
1
1.3k
Other Decks in Technology
See All in Technology
iOSチームとAndroidチームでブランチ運用が違ったので整理してます
sansantech
PRO
0
130
Taming you application's environments
salaboy
0
180
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby Web Application 50 Times Faster
hogelog
3
940
Can We Measure Developer Productivity?
ewolff
1
150
TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論
uhyo
2
1.6k
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
740
AWS Lambda のトラブルシュートをしていて思うこと
kazzpapa3
2
170
スクラム成熟度セルフチェックツールを作って得た学びとその活用法
coincheck_recruit
1
140
ドメインの本質を掴む / Get the essence of the domain
sinsoku
2
150
個人でもIAM Identity Centerを使おう!(アクセス管理編)
ryder472
3
200
10XにおけるData Contractの導入について: Data Contract事例共有会
10xinc
5
610
Featured
See All Featured
Visualization
eitanlees
145
15k
Documentation Writing (for coders)
carmenintech
65
4.4k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Bash Introduction
62gerente
608
210k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
How to Think Like a Performance Engineer
csswizardry
20
1.1k
Done Done
chrislema
181
16k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Facilitating Awesome Meetings
lara
50
6.1k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Transcript
swipe.to/ APIとABIの後方互換性について
swipe.to/ .NETのクラスライブラリ assembly type (has namespace and name) member (field/property/method/event)
swipe.to/ ライブラリの後方互換性? 「ライブラリをバージョンアップしても動く」なら後方互換性がある 「一見動いているけど挙動が変わっていて◦◦を使うとバグる」は今は議論しな い(白目) “API”が「同一」であることが互換性の必要条件 後方互換性の保証されたライブラリの機能は、ある日突然新バージョンでAPIが 変 わって使えなくなることがない =
ちょっと安心
swipe.to/ 動機 Xamarin.Androidのあれやこれやが気に入らないのでやり直したい 何をどうすればやり直せるだろうか? そんなことばかり考えています
swipe.to/ Re:ゼロから始めるXamarin.Android開発?
swipe.to/ まあそれは飛躍なので、今日はもっと地味な話を… 同一のAPIを維持しつつ負の遺産を切り捨てるのはどうすればいい?
swipe.to/ 同一の”API”: 前提 .NETは動的ライブラリの世界 コード中ではメンバー名(name)、型名(fullname)、アセンブリ名で「参照」する アセンブリ名 = (1)name (2)version (3)public
key token (4)culture 参照される実体が物理的に変わることがある(.NETの場合はアセンブリ) どれか1つでも「違う」ものは「違う」コード メンバーの同一性: これは難しいことは何もない フィールドがプロパティになったら「違う」コード メソッド…また後で
swipe.to/ アセンブリ名 = DLLファイル名じゃないの? 1つのアプリケーションで、型名とメンバー名(と種類)が同じものが 複数のアセ ンブリに存在しうる 同じ名前の型やクラスを複数のライブラリが提供して、それぞれに応用ライブラリ があるとき それらを混在できないようにするのは避けたいし、
混在させて実行した時にいわゆるDLL HELLが生じるのを回避したい
swipe.to/ アセンブリの同一性 アセンブリのバージョン番号の「同一性」 4つの数字があるが、通常はビルド番号まで同一のものを要求することはない アセンブリにバージョンと公開鍵トークンが出来た当時: 「アセンブリのバージョンが上がったら別のアセンブリだし、それでも参照して いいという利用者は バインディングリダイレクトして使えるようにしよう」 「公開鍵トークンが違ったら別のアセンブリな」 「秘密鍵は隠匿しておいて、別の発行者が偽物を出せないようにしよう」?
設計上はさまざまな問題を解決した、かのように見える
swipe.to/ 実際に起こったこと(1)公開鍵トークン ECMA標準化 誰でもAPIを実装できなければならない 標準に沿って作られたコードはどの環境でも実行できなければならない 「どこでも実行できる」プログラムが特定のpublic key tokenを前提としたアセン ブリを参照している そのpublic
key tokenを検証できるのはMicrosoftだけ…!? public key tokenは外側からいくらでもでっちあげられる 「偽物」のアセンブリは、ランタイム側のセキュリティ機構によって「検証」で きなければ拒絶される アセンブリ署名は「検証」しなくても実行できる 特に.NET 3.5以降
swipe.to/ mono ECMA標準の実装(もするし、それ以外も見境なく実装) 非標準APIのアセンブリのpublic key tokenもそのまま流用(もちろんMicrosoftは署名 しない) 自分たちのmscorlibがそもそも偽物なのにPE verifierを実装?? 当初からアセンブリ検証はスルー
だいぶ後になって実装された頃にはみんなPEVerifyなんて気にしなくなっていた
swipe.to/ 実際に起こったこと(2)バージョン番号 「バグフィックスリリースを出したらバージョンが変わってファイルを置き換えた ら参照できなくなった」 → いちいちバインディングリダイレクト追加すんのめんどくさい → もうバージョン番号も同じままでリリースしちゃえ → .NET
Frameworkのリリースの時だけバージョン番号を変えよう → さらにAPIの破壊的変更が無い時はバージョン番号も変えないことにしよう (.NET 3.x、.NET 4.5) Silverlightの公開 mscorlib.dll 2.0.50727.* / mscorlib.dll 2.0.5.0 / mscorlib.dll 4.0.
swipe.to/ 実際に起こったこと(3)アセンブリ参照のエイリアス type forwarders .NET2でひっそり導入されて、.NET4でWPFのアセンブリ変更に活用された PresentationFramework.dll → System.Windows*.dll、System.Xaml.dll PCL コンパイル時に参照されるのはダミー
実行されるのは.NET FxやSilverlightやWinPhoneの環境にあるアセンブリ アプリケーションにバンドルしない 参照されるのは、実行時には存在しないアセンブリ (アプリケーションのビル ド時にFacadesのtype forwardersを経由して実体のあるものに差し替え)
swipe.to/ アセンブリ参照の「エイリアス化」 = 「解体」 .NET Frameworkアセンブリの再編成(例: mscorlib.dllの消失) .NET Core 2.0でも同じ変更が加えられた
IDE上の参照設定が簡略化 従来の参照指定: 必要なものは全部列挙しろ(!) MSBuildの<Project>要素にSDK属性を追加 参照アセンブリをいちいち列挙しなくて良い .NET Coreの実行モデル: dotnet run dotnet build: ビルドしたアプリケーションのアセンブリを単体で配布するとい う発想がない
swipe.to/ なぜ「アセンブリ参照」を有名無実化したいのか? 実際のFCLの互換性維持戦略として、既存の型やメンバーを削除することはしない 原則「アセンブリが違うと違う型になる」ので、後方互換性を維持する限りは古 いコードを削除できない フレームワークの肥大化(特にmscorlibやSystem.Web)
swipe.to/ NuGetの時代 ライブラリはNuGetパッケージ名によって追加する時代になってきた パッケージのバージョンが変わるとアセンブリ集合が変わる(!) パッケージのバージョンが変わると依存パッケージ集合が変わる(!) NuGetパッケージは過去バージョンのインストールが容易だし多分ずっと消えない android.support.v*など、外的要因でライブラリ構成が変わるのは避けられない Xamarin的には.NET Standardや.NET Coreでライブラリ構成が変わることすら外的
要因 NuGetを使っている場面でアセンブリ参照を含むAPIを維持するのは「不可能」だし 「意味がない」
swipe.to/ ライブラリ設計時の考慮事項 (1) “API”の同一性の判 断基準 APIとABI API (Application Programming Interface)
ABI (Application Binary Interface) API: ソースコード互換性 ABI: バイナリ互換性 API非互換のライブラリ: 更新したらビルドが通らなくなった! ABI非互換のライブラリ: 更新したら実行時エラーが出るようになった!
swipe.to/ ABI互換の実質的な意義は? public/protectedなメンバーのシグネチャーが変わったらNG(原則) リフレクションで呼び出されることを考えたら、プライベートメンバーも変更すべ きではない? そんなことまで考えていたらキリがない キリがない互換性を要求するやつは悪!と割り切る 例: .NET Runtime
Serialization
swipe.to/ API互換の実質的な意義は? (ABI互換が保たれている前提で) Q: ABI互換性が維持されるのにAPI互換性が損なわれるケースなんてあるの? A1: メソッド引数名 コンパイル時に解決されるのでABIの変更ではない 名前で引数を指定する開発者にAPI互換を要求する権利は無い! …という(強い)
気持ちが必要 特にAPIが自動生成される世界ではメソッド引数名なんて維持できるはずがない
swipe.to/ API互換の実質的な意義は? A2: 定数 コンパイル時に参照側が定数値に置き換えられるため フィールドを定数に変更した! 大抵の場合は問題にならないはず(定数値をもつフィールドは生成される) フィールドから定数に変更して、ついでに型も変更すると危うい (古いアプリ が「フィールド」を参照しているかもしれない)
swipe.to/ API互換の実質的な意義は? A3: 新しい列挙値 コンパイル時のチェックが通らなくなる 実行時に予測不能な値が来ることがある(でも通常のenumでもありうることで は?) まあ「API設計を仕切り直したい」という時は、 こんなチマチマした変更では対応で きないレベルの問題がある…
swipe.to/ 古いコードを切り捨てるための戦略 パッケージ単位で参照してもらうことを前提にする アセンブリを分割する パッケージを分割する 古いパッケージはそれらを全て依存パッケージとして指定する 負の遺産はlegacyみたいなわかりやすい名付で隔離する legacyを切り捨てる これでいい?
swipe.to/ そもそもアセンブリ名のチェックをそもそも排除したい?したくない?