前回(以下のエントリー)の実装を改良して複数のプラグインを読み込んでみます。
MEFでWPFのプラグインを実装する - プログラマーな日々
MEFは.NET4で提供された.NET標準のDIコンテナです。このMEFを使ってWPFのプラグインを実装してみます。
プロジェクト構成
- Pluginプロジェクト
クラスライブラリプロジェクトです。プラグインのインターフェースを定義します。前回と同じです。
- HogePluginプロジェクト
WPFユーザーコントロールライブラリプロジェクトです。プラグインの実装クラスを含みます。ビルドしてアセンブリを所定のディレクトリ(D:\@Sandbox\Plugin)に配置します。前回と同じです。
- FugaPluginプロジェクト
WPFユーザーコントロールライブラリプロジェクトです。プラグインの実装クラスを含みます。ビルドしてアセンブリを所定のディレクトリ(D:\@Sandbox\Plugin)に配置します。今回新たに追加したプロジェクトです。
- Mainプロジェクト
WPFアプリケーションプロジェクトです。プラグインを読み込みます。Pluginプロジェクトを参照しますが、HogePluginプロジェクト、FugaPluginプロジェクトは参照しません。複数プラグインを読み込むように変更します。
Pluginプロジェクト
IPlugin.cs
namespace Plugin { public interface IPlugin { void Execute(); } }
HogePluginプロジェクト
HogeWindow.xaml
<Window x:Class="HogePlugin.HogeWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="HogeWindow" Height="100" Width="300"> </Window>
HogeWindow.xaml.cs
using System.ComponentModel.Composition; using System.Windows; using Plugin; namespace HogePlugin { /// <summary> /// 型を指定してExport属性を指定します。 /// </summary> [Export(typeof(IPlugin))] public partial class HogeWindow : Window, IPlugin { public HogeWindow() { InitializeComponent(); } void IPlugin.Execute() { this.Title = "Hello World, Hoge"; this.Show(); } } }
FugaPluginプロジェクト
FugaWindow.xaml
<Window x:Class="FugaPlugin.FugaWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="FugaWindow" Height="100" Width="300"> </Window>
FugaWindow.xaml.cs
using System.ComponentModel.Composition; using System.Windows; using Plugin; namespace FugaPlugin { /// <summary> /// 型を指定してExport属性を指定します。 /// </summary> [Export(typeof(IPlugin))] public partial class FugaWindow : Window, IPlugin { public FugaWindow() { InitializeComponent(); } void IPlugin.Execute() { this.Title = "Hello World, Fuga"; this.Show(); } } }
Mainプロジェクト
App.xaml
<Application x:Class="Main.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> </Application>
App.xaml.cs
using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Windows; using Plugin; namespace Main { public partial class App : Application { /// <summary> /// ImportMany属性を指定するとこのプロパティに複数のプラグインが読み込まれます。privateなプロパティでもOKです。 /// </summary> [ImportMany] private List<IPlugin> Plugins { get; set; } public App() { this.Plugins = new List<IPlugin>(); this.LoadPlugin(); this.Plugins.ForEach(p => p.Execute()); } /// <summary> /// 所定のディレクトリにあるプラグインdllファイルを読み込みます。 /// </summary> private void LoadPlugin() { using (DirectoryCatalog catalog = new DirectoryCatalog(@"D:\@Sandbox\Plugin", "*.dll")) // すべてのdllファイル using (CompositionContainer container = new CompositionContainer(catalog)) { container.SatisfyImportsOnce(this); } } } }