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
220
.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
510
Building Kotlin Multiplatform Libraries in 2024
atsushieno
0
3.5k
Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話
atsushieno
1
660
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.7k
CLAPオーディオプラグイン is 何?
atsushieno
1
1.3k
Other Decks in Technology
See All in Technology
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
270
C++26 エラー性動作
faithandbrave
2
740
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
130
PHPerのための計算量入門/Complexity101 for PHPer
hanhan1978
5
120
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
300
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
プロダクト開発を加速させるためのQA文化の築き方 / How to build QA culture to accelerate product development
mii3king
1
270
継続的にアウトカムを生み出し ビジネスにつなげる、 戦略と運営に対するタイミーのQUEST(探求)
zigorou
0
560
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
540
AI時代のデータセンターネットワーク
lycorptech_jp
PRO
1
290
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
170
WACATE2024冬セッション資料(ユーザビリティ)
scarletplover
0
200
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Automating Front-end Workflow
addyosmani
1366
200k
YesSQL, Process and Tooling at Scale
rocio
169
14k
A Tale of Four Properties
chriscoyier
157
23k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
A Philosophy of Restraint
colly
203
16k
Building an army of robots
kneath
302
44k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
KATA
mclloyd
29
14k
Unsuck your backbone
ammeep
669
57k
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/ そもそもアセンブリ名のチェックをそもそも排除したい?したくない?