C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2007/11/11 14:56
前回の記事で書いた、C# コードを PowerShell 上で使用する関数が、意外と使えそうなことに気づいた。 ( なので前回の記事のタイトルも変更。 )

で、この関数、実は一つ欠点がある。生成されたアセンブリは現在のアプリケーションドメインにロードされるため即座に利用が可能なわけだが、アプリケーションドメインにロードされたアセンブリはアプリケーションドメインがアンロードされない限りアンロードできない。つまり、コンパイルするたびにアセンブリがロードされメモリを消費していくことになる。

アセンブリの動的なロードは、アプリケーションのプラグイン機能で良く使われる。その際、この問題を回避する方法として用いられるのが、プラグイン用のアプリケーションドメインを別に用意するという方法。異なるアプリケーションドメイン間で通信を行うために、プラグインクラスは MarshalByRefObject クラス (System) を継承する。そうすれば、AppDomain.CreateInstanceAndUnwrap メソッドで生成したプロキシを通して通信が行える。

前回の記事を書いた時は、この問題を考慮したバージョンの関数を次のステップとして作ろうと思ってた。でも、一々 MarshalByRefObject を継承しないといけなくなるし、シリアライズ不可能なオブジェクトは扱えなくなる。これはさすがに PowerShell での実用性がないんじゃないか。おまけにAppDomain.CreateInstanceAndUnwrap メソッドで生成したプロキシが PowerShell から正常に操作できないみたいだし。
そこまでせずとも、今の関数を注意して使えばいいじゃないか。ということで、やめた。


ちなみに、この関数は元々、PowerShell のリリース前 ( 僕がPowerShell を知る前 ) に、コンソール上から C# のコードを動的に実行できるアプリを C# で作ろうとした時に書いたコードの一部を使いまわしたもの。
といっても、そのアプリは CSharpCodeProvider クラスを利用しても実現できないと気が付き ( 一応、単純なコードなら実行できた )  、諦めたんだけど・・・。
たぶん、System.Reflection.Emit 名前空間のクラスを利用して  構文解釈 → MSIL に変換 という処理を実装しなきゃダメ。PowerShell や IronPython を作るのに等しい。



あと、PowerShell 上で C# のコードをコンパイルして使うという試み、すでにやっている方がいたことが判明。
僕の場合、「定義する」ことに重点を置いていたが、こちらは「実行する」ことに重点を置いている。別アプリケーションドメインでの実行も考慮されている。

炎の作品 ― flamework.net ―: PowerShell で C# の実行

炎の作品 ― flamework.net ―: メモリリークのない C# の実行


どうも、MVP のむたぐちさんのブログらしい。 → 勘違いでした、申し訳ないです…。
スポンサーサイト



タグ: .NET C# PowerShell