特定の名前空間のクラスをすべて取得し、動的に実行する方法メモ。
↓のようなプロジェクトの階層になっているとします。
Example(プロジェクトルート) ┗Form1.cs ┗proc ┗IBatch.cs ┗impl ┗BatchA.cs ┗BatchB.cs ┗BatchC.cs
implフォルダ内には、「IBatch.cs」を継承した「BatchA.cs」「BatchB.cs」「BatchC.cs」がいます。
ここでimplフォルダ内のクラスをすべて取得 ⇒ インスタンス生成 ⇒ 実行 というのが今回の目的。
インターフェースと実装は大した処理を書いてないので簡単に。
IBatch.cs, BatchA.cs, BatchB.cs, BatchC.cs
interface IBatch
{
void Execute();
}
class BatchA : IBatch
{
public void Execute()
{
Console.WriteLine("BatchA の処理内容");
}
}
class BatchB : IBatch
{
public void Execute()
{
Console.WriteLine("BatchB の処理内容");
}
}
class BatchC : IBatch
{
public void Execute()
{
Console.WriteLine("BatchC の処理内容");
}
}
続いてForm1.cs
フォームロード時に実行しています。
using System;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using Example.proc;
namespace Example
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// アセンブリ取得
Assembly assm = Assembly.GetExecutingAssembly();
// 指定した名前空間のクラスをすべて取得
var types = assm.GetTypes()
.Where(p => p.Namespace == "Example.proc.impl")
.OrderBy(o => o.Name)
.Select(s => s);
// 取得したクラスのExecuteをすべて実行
foreach (Type t in types)
{
IBatch batInstance = (IBatch)Activator.CreateInstance(t);
batInstance.Execute();
}
}
}
}
実行結果
BatchA の処理内容 BatchB の処理内容 BatchC の処理内容
ちゃんと実行されました。
要点だけもう一度。
以上。