プロファイル

.NET にもいろいろなバージョンが出てて。 でも、主な差はプロファイルの差。

別ページ(「実行基盤」 )でも説明しているけども

いろいろな .NET
いろいろな .NET

最初にこういう「プロファイルの差」が出始めたのは、.NET 2と3がin-placeだったからだっけ? Clinet Profileってのができたのも。

で、開発機と配布先でのプロファイルの差が問題に

プロファイルの差による問題
プロファイルの差による問題

Full .NETが入ってるマシンで Client Profile ターゲットの開発するために 解決策として導入された方法が、参照アセンブリ。

参照アセンブリ

実行時に見てるのと、Visual Studio 上で参照してるのが違う。 リフレクションで実行時に見てるのが何かを調べて出す例を VS 上のはプロパティ ウィンドウで。

参照アセンブリの場所
参照アセンブリの場所

実行時に見てるのは

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine(typeof(int).Assembly.Location);
        Console.WriteLine(typeof(Uri).Assembly.Location);
    }
}
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll

Visual Studio から見ているアセンブリの中身をのぞくと

参照アセンブリの中身
参照アセンブリの中身

中身からっぽ。 つまり、実際に動かせるアセンブリじゃなくて、 メタデータ(どういうクラスがあって、どういうメソッドを持っているか)を参照するためだけのもの。

これで、Full プロファイルが入っている開発環境で、 Client プロファイルをターゲットにした開発とかができる。

Windows ストア アプリ

実は、Windows ストア アプリからも、実行時にはデスクトップ版と全く同じアセンブリを参照してる。

Visual Studio 上からは、参照アセンブリだけ切り替えて別プロファイルに見せかけてる。 リフレクションを使えばデスクトップ版で使える全機能を使える。

そんなことしてまでわざわざ制限かけてるのは、セキュリティ的理由と、将来的にサポートできなくなる可能性を今のうちから避けるという理由。

今は、実装手間を考えて「実は同じものを見てる」実装になってるけども。ずっとそうである保証ない。 将来的に、レガシー削除してしまっている Core プロファイル(Windows ストア アプリから参照してる方)の方がサポート期間が長かったりする可能性ある。

Portable Class Library

今は、もっとプロファイルが増えてる Silverlight、Windows Store Apps、Windows Phone、… Client プロファイルと Full プロファイルみたいに単純な包含関係(上位互換)でもない。

PCL: プロファイルでターゲットを切り替えれるものの、1度ターゲットを決めたらそれ以外で使えなくなった。 それじゃまずいんで、PCL 作った。

共通部分を作って、フラグ的に管理。 まあ、ぶっちゃけ、{ A, B, C } に対して、{ A, B, C, A&B, B&C, C&A, A&B&C } みたいな参照アセンブリを作って置いておく仕組み。 ターゲット パックってのを入れたらターゲット増やせる。

余談: 型フォワーディング

型フォワーディング(type forward)

「同じクラスを持っているのに PCL で使えない」みたいな状況もあって。 .NET は「クラスと、そのクラスがどこのアセンブリで定義されているか」を見てコードを実行しているので、 型名、メンバー構成が一緒なだけじゃだめで、どのアセンブリで定義されてるかも一致してないとダメ。 「同じクラスが別のアセンブリで定義されている」とかだと PCL で使えない。

例えば、ObservableCollection<T>。 WindowsBase.dll → System.dll/System.Windows.dll → System.ObjectModel.dll。

これじゃ PCL の利便性的にいまいちなので、 .NET 4.5 世代で整理しまくった(クラスを定義するアセンブリを大規模変更)。

一方で、過去との互換性を取るために、以前のアセンブリでも同名のクラスが定義されているかのように見せかける仕組みが必要。 それが TypeForwardedTo 属性。 .NET 4.5 の System.dll の中身のぞくと大量に。

余談ついでに、.NET 4.5 のアセンブリ整理、DLL 間の相互依存が減るように整理されてる。

更新履歴

ブログ