DBからのアセンブリロード

http://d.hatena.ne.jp/akiramei/20040607#p1のデータベース版。(^^;
Program.exeとそれが呼び出しているCalc.dllを先日のデータベースに格納しているとします。
で、次のようなランチャープログラムを用意します。

using System;
using System.Security.Policy;
using System.Configuration;
using System.Reflection;
using MySql.Data.MySqlClient;

class Program
{
  [STAThread]
  static void Main(string args) {
    if (args.Length < 1)
      return;
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyAssemblyResolve);
    Assembly asm = Assembly.Load(GetAssembly(args[0]));
    asm.EntryPoint.Invoke(null, new object{args});
  }

  // 参照の解決
  public static Assembly MyAssemblyResolve(object sender, ResolveEventArgs args) {
    string name = args.Name.Split(',')[0] + ".dll";
    byte image = GetAssembly(name);
    if (image != null)
      return Assembly.Load(image);
    return null;
  }

  // 指定したアセンブリをDBから読み込む
  static byte GetAssembly(string name) {
    byte image = null;
    string dbstr = ConfigurationSettings.AppSettings["ConnectionString"];
    string sql = String.Format("select image from files where name='{0}'", name);
    MySqlConnection conn = null;
    try {
      conn = new MySqlConnection(dbstr);
      conn.Open();
      MySqlCommand cmd = new MySqlCommand(sql, conn);
      image = (byte)cmd.ExecuteScalar();
    }
    catch (MySqlException e) {
      Console.WriteLine(e.Message);
    }
    finally {
      if (conn != null) {
        conn.Close();
        conn = null;
      }
    }
    return image;
  }
}

上記ソースをLauncher.exeとかでビルドします。で、

> Launcher.exe Program.exe

とか、実行するとProgram.exeをDBから読み込んで実行し、参照アセンブリも必要になれば随時データベースから読み込みます。

参照解決の度にデータベースに接続しているのは突っ込まない方向でお願いします・・・(^^;

(追記) どうも、Program.exeはテンポラリファイルに落とさないとうまく動かないみたい。動いたと思ったら、実行ディレクトリにProgram.exeがあった所為でした。あとで、ソース直しておきます・・・

で、別ドメインで動かすのをやめました。AppDomain.Loadはカレントドメインで使うことを想定しているらしい。