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
620
Building Kotlin Multiplatform Libraries in 2024
atsushieno
0
3.6k
Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話
atsushieno
1
680
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.2k
learning how DAWs work, with Zrythm
atsushieno
0
1.2k
What for, Where and How to Adopt MIDI 2.0
atsushieno
0
1.3k
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
Azureの開発で辛いところ
re3turn
0
240
Evolving Architecture
rainerhahnekamp
3
250
新卒1年目、はじめてのアプリケーションサーバー【IBM WebSphere Liberty】
ktgrryt
0
120
Cloudflareで実現する AIエージェント ワークフロー基盤
kmd09
0
290
embedパッケージを深掘りする / Deep Dive into embed Package in Go
task4233
1
220
シフトライトなテスト活動を適切に行うことで、無理な開発をせず、過剰にテストせず、顧客をビックリさせないプロダクトを作り上げているお話 #RSGT2025 / Shift Right
nihonbuson
3
2.1k
#TRG24 / David Cuartielles / Post Open Source
tarugoconf
0
580
KMP with Crashlytics
sansantech
PRO
0
240
カップ麺の待ち時間(3分)でわかるPartyRockアップデート
ryutakondo
0
140
【NGK2025S】動物園(PINTO_model_zoo)に遊びに行こう
kazuhitotakahashi
0
240
Kotlin Multiplatformのポテンシャル
recruitengineers
PRO
2
150
Goで実践するBFP
hiroyaterui
1
120
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Optimizing for Happiness
mojombo
376
70k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Agile that works and the tools we love
rasmusluckow
328
21k
Speed Design
sergeychernyshev
25
740
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Code Review Best Practice
trishagee
65
17k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Why Our Code Smells
bkeepers
PRO
335
57k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.6k
What's in a price? How to price your products and services
michaelherold
244
12k
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/ そもそもアセンブリ名のチェックをそもそも排除したい?したくない?