Silverlight 4 と .NET Framework 4 のアセンブリ共有について

エントリを書くのも久し振りなんですが、Silverlight 4ベータが公開されてから .NET Framework 4 とのアセンブリの共有ができるという情報が公開されています。このSilverlightとの共有に関して、情報を整理しようと考えています。詳細は、CLRチームのエントリに記載されていますが、そこに記載されている4つのアセンブリが以下になります。

  1. mscorlib.dll(System 名前空間)
  2. System.dll(System.Net 名前空間など)
  3. System.Core.dll(System 名前空間で、LINQやDLRなど)
  4. Microsoft.VisualBasic.dll(Microsoft.VisualBasic 名前空間で VBで使用するMyや関数などが含まれます)

上記のアセンブリに含まれているライブラリを使用しているプログラムであれば、CoreCLR とデスクトップ CLR がバイナリレベルで実行が可能になることをアセンブリの共有と呼んでいます。アセンブリの共有で実現できることは、以下のポータビリティです。

  • バイナリレベルでの互換性
  • ライブラリの互換性

先にご紹介した CLR チームのエントリでは、.NET Framework 4対応の WPF アプリとSilverlight 用のライブラリプロジェクトで動作するという具体例を紹介しています。が、裏側で何が行われているかを推論してみたいと考えています。私は、この動作は以下のようなことを行っていると考えています。

  • CoreCLR のアセンブリローダーのバインディング ポリシーの設定
  • デスクトップ CLR のアセンブリローダーのバインディング ポリシーの設定

たとえばデスクトップ CLR 用の mscorlib.dll は約4.83MBあります。これに対して Silverlight のランタイム サイズの目標は2MBになっています(Silverlight 3では約3MBで、mscorlibは約1.4MBです)。このサイズが最終的にデスクトップと同じになるとは、考えられません。というか、MacOS に .NET Framework 4 が提供されませんので、Silverlight 用とデスクトップ CLR 用に別々のライブラリが用意されるのが当たり前と考えることができるからです。このように考えていくと、一部のクラスなどでデスクトップ CLR と CoreCLR 上で振る舞いが異なることが考えられます。具体的には、Silverlight では System.IO 名前空間の大半には SecurityCritical 属性が付与されています。 つまりブラウザ上のサンドボックスで動作する関係で、危険な行為を行えるメソッドに対しては安全とマークされているライブラリ(ランタイムライブラリ)からしか呼び出すことができないようになっているのです。このことは、Silverlight 4 と .NET Framework 4 でアセンブリを共有する場合に、以下のことに注意する必要があることを意味しています。

  • CoreCLR で SecurityCritical 属性が付与されているメンバーを使用しない

また Silverlight 3までは System.Uri クラスで「file://....」という記述はできませんでした。Silverlight 1.1 アルファと呼んでいたプレビューの頃は使用できましたが、製品版では削除されたプロトコルになっているのです。したがって、ライブラリの互換性自体は向上しますが、機能的に Silverlight では制限されているメンバーが存在すると考えるのが妥当だと考えられます。

とは言っても、プログラムで使用する機能をライブラリ化(DLL)して Silverlight や ASP.NET、または WPF アプリケーションで共通して利用するというシナリオに置いて、保守するソースコードの種類が減りますので、使い方さえ間違わなければ効率の良いプログラムが記述できることでしょう。

PS. .NET Framework 4 と同様に DLR は、System.Core に含まれていますが、 dynamic キーワードなどが含まれるかまでは調べきれていません。