Assembly.LoadFrom を使って別のアセンブリにあるフォームを起動する | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/2312
上記なところで、Assembly.LoadFrom メソッドを使うと動的にアセンブリをロードすることができる、って話をしましたが、実はプラグインでなければ【動的】である必要はないわけで、あらかじめ【参照設定】などでアセンブリを指定しておく方法もあります。
つまりは、
1 2 3 | Dim cname as string = "クラス名" Dim t as Type = Type. GetType ( cname ) Dim f as Form = System.Activator.CreateInstance(t) |
な感じで、Type から直接作ればよいわけです。
実は前回、なんでわざわざ動的ロードにしたのかなぁ、と思っていたら、この cname が参照設定先の別のアセンブリにあると、単純にクラス名(例えば、FormSub とか)だけではオブジェクトを作成できなかったからなのです。
アセンブリの構成が、
SampleMain.exe
+ FormMain
のように単一のアセンブリに入っていれば、そのまま Type.GetType(“FormMain”) でロードができるのですが、
SampleMain.exe
+ FormMain
SampleSub.exe
+ FormSub
のように、Main.exe から Sub.exe を【参照設定】している場合は、Main.exe の中では、Type.GetType(“FormSub”) ができません。
別アセンブリの場合は、【修飾名】が必要って訳です。
で、この修飾名はどうやって取り出すかというと、AssemblyQualifiedName で取り出します。
Type.GetType メソッド (String) (System)
http://msdn.microsoft.com/ja-jp/library/w3f99sx1(v=VS.80).aspx
Type.AssemblyQualifiedName プロパティ (System)
http://msdn.microsoft.com/ja-jp/library/system.type.assemblyqualifiedname(v=VS.80).aspx
なにやら、ややこしいことが書いてありますが、要は試しのプログラムを作って AssemblyQualifiedName プロパティで取り出してみればば良いわけです。下記のように試してみます。
1 2 | Dim frm as new FormSub Debug.Print( frm. GetType .AssemblyQualifiedName ) |
すると、「FormSub, SampleSub, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null」のように修飾名が取れるので、そのままクラス名として利用します。
1 2 3 | Dim cname as string = "FormSub, SampleSub, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Dim t as Type = Type. GetType ( cname ) Dim f as Form = System.Activator.CreateInstance(t) |
ロードする対象のクラスを切り替えたいとき(画面を切り替えたいとき)は、クラス名の「FormSub」を変えれば ok ですね。
実は、ガベージコレクション時にあまり使っていないオブジェクトが勝手に開放されて、落ちているっぽい、という現象に出会ったので動的ロードじゃなくて参照設定からに切り替えたのですが…どうも違ったらしい。他のところのバグらしい。ってな話。