ManagedDll を動的に読み込むあれこれ
流派は2つ。
Assembly 使って、動的にリンクする方法
http://athomejp.com/goldfish/vcs/assemblycall.asp
AppDomain 使って、動的にロードする方法
http://d.hatena.ne.jp/akiramei/20071111/1194786373
前者のほうが簡易だけど、後者はアンロードできるそうな。
デカいDLLなら迷わず後者だな。
見たい人だけサンプル
Assembly クラスによるロード
Assembly クラスで DLL を決め打ちで読み込み、ロードしてくる方法。インスタンスはActivatorで無理やり生成する。
インターフェース用意しとくと、アクセスが容易。
もし、インターフェースを用意しないのであれば、Type.GetMethod や、Type.GetProperty でMethodInfo とか PropertyInfo 経由でごにょごにょしなきゃいけない。
public interface IHello { string getDllMessage(); }
で、これを継承してクラス(DLL)作成
namespace Hello { public class SampleHello : DinamicDLLLoad.IHello { public string getDllMessage() { return "Mr,Azalea"; } } }
そして、これを動的に読み込むコード
static void Main(string[] args) { while (true) { System.Threading.Thread.Sleep(500); if (System.IO.File.Exists("Hello.dll")) break; Console.WriteLine("Cannot find Hello.dll"); } try { /* DLL を指定して読み込む */ Assembly assembly = Assembly.LoadFrom("Hello.dll"); Module module = assembly.GetModule("Hello.dll"); Type type = module.GetType("Hello.SampleHello"); /* インスタンスを作成する */ IHello hello = Activator.CreateInstance(type) as IHello; Console.WriteLine("Hello " + hello.getDllMessage()); } catch (Exception) { } Console.WriteLine("Push any key to exit;"); Console.ReadLine(); }
AppDomain 使って読み込む
こっちの実装だと、アンロードが可能になる。
扱い的には子プロセス(みたいなもの)を立てて、ソコからさらに動的にクラスインスタンスを持ってくる。
だから、プロセス(Domain)が死ねば、dll も開放されるというワケ。
static void Main(string[] args) { while (true) { System.Threading.Thread.Sleep(500); if (System.IO.File.Exists("Hello.dll")) break; Console.WriteLine("Cannot find Hello.dll"); } AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; /* シャドウコピーで dll を使うので、途中削除OK */ setup.ShadowCopyFiles = "true"; AppDomain mainDomain = AppDomain.CreateDomain("SampleCode", null, setup); IHello hello = mainDomain.CreateInstanceAndUnwrap("Hello", "Hello.SampleHello") as IHello; Console.WriteLine("Push any key to exit;"); Console.ReadLine(); }