DoboWiki
Top
> .NETプログラミング研究/39 をテンプレートにして作成
.NETプログラミング研究/39 をテンプレートにして作成
開始行:
#title(.NETプログラミング研究 第39号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第39号 [#g3a86034]
**.NET Tips [#ob24bd81]
**プラグイン機能を持つアプリケーションを作成する - その1...
#column(注意){{
この記事の最新版は「[[プラグイン機能を持つアプリケーショ...
}}
Adobe PhotoshopやBecky! Internet Mailなどのアプリケーショ...
-[[Adobe Photoshop>http://www.adobe.co.jp/products/photos...
-[[RimArts - Becky! Internet Mail>http://www.rimarts.co.j...
(プラグインが何だか分からないという方は、「アスキー デジ...
-[[ASCII24 - アスキー デジタル用語辞典 - プラグイン>http:...
-[[IT用語辞典 e-Words : プラグイン 【plug-in】>http://e-...
早速ですが、プラグイン機能の実現のために参考になりそうな...
-[[Developer Fusion - Writing Plugin-Based Applications>h...
-[[DevSource - Building Plug-ins with C# .NET>http://www....
-[[SA Developer .Net - PluginFX - An extensible plugin fr...
-[[The Code Project - Plugin Architecture using C#>http:/...
-[[The Code Project - Plug-ins in C#>http://www.codeproje...
これらの記事で紹介されている方法は基本的にはほとんど同じ...
***インターフェイスの作成 [#zd8eb067]
理屈は置いておき、実際にプラグインを作成してみましょう。
ここで作成するプラグインは、プラグインの名前を返す機能と...
Visual Studio .NETでは、クラスライブラリのプロジェクトを...
(Visual Studio .NETのVB.NETの場合は、プロジェクトのプロ...
#code(vbnet){{
Imports System
Namespace Plugin
Public Interface IPlugin
ReadOnly Property Name() As String
Function Run(ByVal str As String) As String
End Interface
End Namespace
}}
#code(csharp){{
using System;
namespace Plugin
{
public interface IPlugin
{
string Name {get;}
string Run(string str);
}
}
}}
***プラグインの作成 [#p3636fd2]
次に、このインターフェイスを基に、プラグインを作ります。...
ここでは渡された文字列の文字数を返すプラグインを作成する...
#code(vbnet){{
Imports System
Namespace CountChars
Public Class CountChars
Implements Plugin.IPlugin
Public ReadOnly Property Name1() As String _
Implements Plugin.IPlugin.Name
Get
Return "文字数取得"
End Get
End Property
Public Function Run1(ByVal str As String) As Stri...
Implements Plugin.IPlugin.Run
Return str.Length.ToString()
End Function
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace CountChars
{
public class CountChars : Plugin.IPlugin
{
public string Name
{
get
{
return "文字数取得";
}
}
public string Run(string str)
{
return str.Length.ToString();
}
}
}
}}
***プラグインを使うアプリケーションの作成 [#ab3248a6]
残るはプラグインを使用するメインアプリケーションの作成で...
まずインストールされているプラグインを探す方法についてで...
またプラグインクラスのインスタンスを作成するには、Activat...
それでは実際に作成してみましょう。ここではメインアプリは...
まずはプラグインを扱うクラス("PluginInfo")を作成します。...
#code(vbnet){{
Imports System
Namespace MainApplication
''' <summary>
''' プラグインに関する情報
''' </summary>
Public Class PluginInfo
Private _location As String
Private _className As String
''' <summary>
''' PluginInfoクラスのコンストラクタ
''' </summary>
''' <param name="path">アセンブリファイルのパス</...
''' <param name="cls">クラスの名前</param>
Private Sub New(ByVal path As String, ByVal cls A...
Me._location = path
Me._className = cls
End Sub
''' <summary>
''' アセンブリファイルのパス
''' </summary>
Public ReadOnly Property Location() As String
Get
Return _location
End Get
End Property
''' <summary>
''' クラスの名前
''' </summary>
Public ReadOnly Property ClassName() As String
Get
Return _className
End Get
End Property
''' <summary>
''' 有効なプラグインを探す
''' </summary>
''' <returns>有効なプラグインのPluginInfo配列</re...
Public Shared Function FindPlugins() As PluginInf...
Dim plugins As New System.Collections.ArrayList
'IPlugin型の名前
Dim ipluginName As String = _
GetType(Plugin.IPlugin).FullName
'プラグインフォルダ
Dim folder As String = _
System.IO.Path.GetDirectoryName( _
System.Reflection.Assembly. _
GetExecutingAssembly().Location)
folder += "\plugins"
If Not System.IO.Directory.Exists(folder) Then
Throw New ApplicationException( _
"プラグインフォルダ""" + folder + _
"""が見つかりませんでした。")
End If
'.dllファイルを探す
Dim dlls As String() = _
System.IO.Directory.GetFiles(folder, "*.d...
Dim dll As String
For Each dll In dlls
Try
'アセンブリとして読み込む
Dim asm As System.Reflection.Assembly...
System.Reflection.Assembly.LoadFr...
Dim t As Type
For Each t In asm.GetTypes()
'アセンブリ内のすべての型について、
'プラグインとして有効か調べる
If t.IsClass AndAlso t.IsPublic A...
Not t.IsAbstract AndAlso _
Not (t.GetInterface(ipluginNa...
Is Nothing) Then
'PluginInfoをコレクションに追...
plugins.Add( _
New PluginInfo(dll, t.Ful...
End If
Next t
Catch
End Try
Next dll
'コレクションを配列にして返す
Return CType(plugins.ToArray( _
GetType(PluginInfo)), PluginInfo())
End Function
''' <summary>
''' プラグインクラスのインスタンスを作成する
''' </summary>
''' <returns>プラグインクラスのインスタンス</retu...
Public Function CreateInstance() As Plugin.IPlugin
Try
'アセンブリを読み込む
Dim asm As System.Reflection.Assembly = _
System.Reflection.Assembly.LoadFrom(M...
'クラス名からインスタンスを作成する
Return CType(asm.CreateInstance(Me.ClassN...
Plugin.IPlugin)
Catch
End Try
End Function
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace Plugin
{
/// <summary>
/// プラグインに関する情報
/// </summary>
public class PluginInfo
{
private string _location;
private string _className;
/// <summary>
/// PluginInfoクラスのコンストラクタ
/// </summary>
/// <param name="path">アセンブリファイルのパス</param>
/// <param name="cls">クラスの名前</param>
private PluginInfo(string path, string cls)
{
this.Location = path;
this.ClassName = cls;
}
/// <summary>
/// アセンブリファイルのパス
/// </summary>
public string Location
{
get {return _location;}
}
/// <summary>
/// クラスの名前
/// </summary>
public string ClassName
{
get {return _className;}
}
/// <summary>
/// 有効なプラグインを探す
/// </summary>
/// <returns>有効なプラグインのPluginInfo配列</returns>
public static PluginInfo[] FindPlugins()
{
System.Collections.ArrayList plugins =
new System.Collections.ArrayList();
//IPlugin型の名前
string ipluginName = typeof(Plugin.IPlugin).FullName;
//プラグインフォルダ
string folder = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly
.GetExecutingAssembly().Location);
folder += "\\plugins";
if (!System.IO.Directory.Exists(folder))
throw new ApplicationException(
"プラグインフォルダ\"" + folder +
"\"が見つかりませんでした。");
//.dllファイルを探す
string[] dlls =
System.IO.Directory.GetFiles(folder, "*.dll");
foreach (string dll in dlls)
{
try
{
//アセンブリとして読み込む
System.Reflection.Assembly asm =
System.Reflection.Assembly.LoadFrom(dll);
foreach (Type t in asm.GetTypes())
{
//アセンブリ内のすべての型について、
//プラグインとして有効か調べる
if (t.IsClass && t.IsPublic && !t.IsAbstract &&
t.GetInterface(ipluginName) != null)
{
//PluginInfoをコレクションに追加する
plugins.Add(
new PluginInfo(dll, t.FullName));
}
}
}
catch
{
}
}
//コレクションを配列にして返す
return (PluginInfo[]) plugins.ToArray(typeof(PluginInf...
}
/// <summary>
/// プラグインクラスのインスタンスを作成する
/// </summary>
/// <returns>プラグインクラスのインスタンス</returns>
public Plugin.IPlugin CreateInstance()
{
try
{
//アセンブリを読み込む
System.Reflection.Assembly asm =
System.Reflection.Assembly.LoadFrom(this.Location);
//クラス名からインスタンスを作成する
return (Plugin.IPlugin)
asm.CreateInstance(this.ClassName);
}
catch
{
return null;
}
}
}
}
}}
FindPluginsメソッドが多少複雑ですので、簡単に説明しておき...
ここまで来たら、後は簡単です。PluginInfoクラスを使ったメ...
#code(vbnet){{
Imports System
Namespace MainApplication
Public Class PluginHost
'/ <summary>
'/ エントリポイント
'/ </summary>
<STAThread()> _
Public Shared Sub Main()
'インストールされているプラグインを調べる
Dim pis As PluginInfo() = PluginInfo.FindPlug...
'すべてのプラグインクラスのインスタンスを作成...
Dim plugins(pis.Length - 1) As Plugin.IPlugin
Dim i As Integer
For i = 0 To plugins.Length - 1
plugins(i) = pis(i).CreateInstance()
Next i
'有効なプラグインを表示し、使用するプラグイン...
Dim number As Integer = -1
Do
For i = 0 To plugins.Length - 1
Console.WriteLine("{0}:{1}", i, plugi...
Next i
Console.WriteLine( _
"使用するプラグインの番号を入力してく...
Try
number = Integer.Parse(Console.ReadLi...
Catch
End Try
Loop While number < 0 Or number >= pis.Length
Console.WriteLine(plugins(number).Name + " を...
'プラグインに渡す文字列の入力を促す
Console.WriteLine("文字列を入力してください。...
Dim str As String = Console.ReadLine()
'プラグインのRunメソッドを呼び出して結果を取...
Dim result As String = plugins(number).Run(str)
'結果の表示
Console.WriteLine("結果:")
Console.WriteLine(result)
Console.ReadLine()
End Sub
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace MainApplication
{
public class PluginHost
{
/// <summary>
/// エントリポイント
/// </summary>
[STAThread]
static void Main(string[] args)
{
//インストールされているプラグインを調べる
PluginInfo[] pis = Plugin.PluginInfo.FindPlugins();
//すべてのプラグインクラスのインスタンスを作成する
Plugin.IPlugin[] plugins = new Plugin.IPlugin[pis.Leng...
for (int i = 0; i < plugins.Length; i++)
plugins[i] = pis[i].CreateInstance();
//有効なプラグインを表示し、使用するプラグインを選ばせる
int number = -1;
do
{
for (int i = 0; i < plugins.Length; i++)
Console.WriteLine("{0}:{1}", i, plugins[i].Name);
Console.WriteLine(
"使用するプラグインの番号を入力してください。:");
try
{
number = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("数字を入力してください。");
}
} while (number < 0 || number >= pis.Length);
Console.WriteLine(plugins[number].Name + " を使用しま...
//プラグインに渡す文字列の入力を促す
Console.WriteLine("文字列を入力してください。:");
string str = Console.ReadLine();
//プラグインのRunメソッドを呼び出して結果を取得する
string result = plugins[number].Run(str);
//結果の表示
Console.WriteLine("結果:");
Console.WriteLine(result);
Console.ReadLine();
}
}
}
}}
メインアプリ実行前に実行ファイルのあるフォルダに"plugins"...
基本的なプラグイン機能の実現方法は以上です。しかしより高...
この方法については、次回、Windowsアプリケーションを例に紹...
**コメント [#w1acf1e8]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-08-16 (月) 06:00:00,DOB...
終了行:
#title(.NETプログラミング研究 第39号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第39号 [#g3a86034]
**.NET Tips [#ob24bd81]
**プラグイン機能を持つアプリケーションを作成する - その1...
#column(注意){{
この記事の最新版は「[[プラグイン機能を持つアプリケーショ...
}}
Adobe PhotoshopやBecky! Internet Mailなどのアプリケーショ...
-[[Adobe Photoshop>http://www.adobe.co.jp/products/photos...
-[[RimArts - Becky! Internet Mail>http://www.rimarts.co.j...
(プラグインが何だか分からないという方は、「アスキー デジ...
-[[ASCII24 - アスキー デジタル用語辞典 - プラグイン>http:...
-[[IT用語辞典 e-Words : プラグイン 【plug-in】>http://e-...
早速ですが、プラグイン機能の実現のために参考になりそうな...
-[[Developer Fusion - Writing Plugin-Based Applications>h...
-[[DevSource - Building Plug-ins with C# .NET>http://www....
-[[SA Developer .Net - PluginFX - An extensible plugin fr...
-[[The Code Project - Plugin Architecture using C#>http:/...
-[[The Code Project - Plug-ins in C#>http://www.codeproje...
これらの記事で紹介されている方法は基本的にはほとんど同じ...
***インターフェイスの作成 [#zd8eb067]
理屈は置いておき、実際にプラグインを作成してみましょう。
ここで作成するプラグインは、プラグインの名前を返す機能と...
Visual Studio .NETでは、クラスライブラリのプロジェクトを...
(Visual Studio .NETのVB.NETの場合は、プロジェクトのプロ...
#code(vbnet){{
Imports System
Namespace Plugin
Public Interface IPlugin
ReadOnly Property Name() As String
Function Run(ByVal str As String) As String
End Interface
End Namespace
}}
#code(csharp){{
using System;
namespace Plugin
{
public interface IPlugin
{
string Name {get;}
string Run(string str);
}
}
}}
***プラグインの作成 [#p3636fd2]
次に、このインターフェイスを基に、プラグインを作ります。...
ここでは渡された文字列の文字数を返すプラグインを作成する...
#code(vbnet){{
Imports System
Namespace CountChars
Public Class CountChars
Implements Plugin.IPlugin
Public ReadOnly Property Name1() As String _
Implements Plugin.IPlugin.Name
Get
Return "文字数取得"
End Get
End Property
Public Function Run1(ByVal str As String) As Stri...
Implements Plugin.IPlugin.Run
Return str.Length.ToString()
End Function
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace CountChars
{
public class CountChars : Plugin.IPlugin
{
public string Name
{
get
{
return "文字数取得";
}
}
public string Run(string str)
{
return str.Length.ToString();
}
}
}
}}
***プラグインを使うアプリケーションの作成 [#ab3248a6]
残るはプラグインを使用するメインアプリケーションの作成で...
まずインストールされているプラグインを探す方法についてで...
またプラグインクラスのインスタンスを作成するには、Activat...
それでは実際に作成してみましょう。ここではメインアプリは...
まずはプラグインを扱うクラス("PluginInfo")を作成します。...
#code(vbnet){{
Imports System
Namespace MainApplication
''' <summary>
''' プラグインに関する情報
''' </summary>
Public Class PluginInfo
Private _location As String
Private _className As String
''' <summary>
''' PluginInfoクラスのコンストラクタ
''' </summary>
''' <param name="path">アセンブリファイルのパス</...
''' <param name="cls">クラスの名前</param>
Private Sub New(ByVal path As String, ByVal cls A...
Me._location = path
Me._className = cls
End Sub
''' <summary>
''' アセンブリファイルのパス
''' </summary>
Public ReadOnly Property Location() As String
Get
Return _location
End Get
End Property
''' <summary>
''' クラスの名前
''' </summary>
Public ReadOnly Property ClassName() As String
Get
Return _className
End Get
End Property
''' <summary>
''' 有効なプラグインを探す
''' </summary>
''' <returns>有効なプラグインのPluginInfo配列</re...
Public Shared Function FindPlugins() As PluginInf...
Dim plugins As New System.Collections.ArrayList
'IPlugin型の名前
Dim ipluginName As String = _
GetType(Plugin.IPlugin).FullName
'プラグインフォルダ
Dim folder As String = _
System.IO.Path.GetDirectoryName( _
System.Reflection.Assembly. _
GetExecutingAssembly().Location)
folder += "\plugins"
If Not System.IO.Directory.Exists(folder) Then
Throw New ApplicationException( _
"プラグインフォルダ""" + folder + _
"""が見つかりませんでした。")
End If
'.dllファイルを探す
Dim dlls As String() = _
System.IO.Directory.GetFiles(folder, "*.d...
Dim dll As String
For Each dll In dlls
Try
'アセンブリとして読み込む
Dim asm As System.Reflection.Assembly...
System.Reflection.Assembly.LoadFr...
Dim t As Type
For Each t In asm.GetTypes()
'アセンブリ内のすべての型について、
'プラグインとして有効か調べる
If t.IsClass AndAlso t.IsPublic A...
Not t.IsAbstract AndAlso _
Not (t.GetInterface(ipluginNa...
Is Nothing) Then
'PluginInfoをコレクションに追...
plugins.Add( _
New PluginInfo(dll, t.Ful...
End If
Next t
Catch
End Try
Next dll
'コレクションを配列にして返す
Return CType(plugins.ToArray( _
GetType(PluginInfo)), PluginInfo())
End Function
''' <summary>
''' プラグインクラスのインスタンスを作成する
''' </summary>
''' <returns>プラグインクラスのインスタンス</retu...
Public Function CreateInstance() As Plugin.IPlugin
Try
'アセンブリを読み込む
Dim asm As System.Reflection.Assembly = _
System.Reflection.Assembly.LoadFrom(M...
'クラス名からインスタンスを作成する
Return CType(asm.CreateInstance(Me.ClassN...
Plugin.IPlugin)
Catch
End Try
End Function
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace Plugin
{
/// <summary>
/// プラグインに関する情報
/// </summary>
public class PluginInfo
{
private string _location;
private string _className;
/// <summary>
/// PluginInfoクラスのコンストラクタ
/// </summary>
/// <param name="path">アセンブリファイルのパス</param>
/// <param name="cls">クラスの名前</param>
private PluginInfo(string path, string cls)
{
this.Location = path;
this.ClassName = cls;
}
/// <summary>
/// アセンブリファイルのパス
/// </summary>
public string Location
{
get {return _location;}
}
/// <summary>
/// クラスの名前
/// </summary>
public string ClassName
{
get {return _className;}
}
/// <summary>
/// 有効なプラグインを探す
/// </summary>
/// <returns>有効なプラグインのPluginInfo配列</returns>
public static PluginInfo[] FindPlugins()
{
System.Collections.ArrayList plugins =
new System.Collections.ArrayList();
//IPlugin型の名前
string ipluginName = typeof(Plugin.IPlugin).FullName;
//プラグインフォルダ
string folder = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly
.GetExecutingAssembly().Location);
folder += "\\plugins";
if (!System.IO.Directory.Exists(folder))
throw new ApplicationException(
"プラグインフォルダ\"" + folder +
"\"が見つかりませんでした。");
//.dllファイルを探す
string[] dlls =
System.IO.Directory.GetFiles(folder, "*.dll");
foreach (string dll in dlls)
{
try
{
//アセンブリとして読み込む
System.Reflection.Assembly asm =
System.Reflection.Assembly.LoadFrom(dll);
foreach (Type t in asm.GetTypes())
{
//アセンブリ内のすべての型について、
//プラグインとして有効か調べる
if (t.IsClass && t.IsPublic && !t.IsAbstract &&
t.GetInterface(ipluginName) != null)
{
//PluginInfoをコレクションに追加する
plugins.Add(
new PluginInfo(dll, t.FullName));
}
}
}
catch
{
}
}
//コレクションを配列にして返す
return (PluginInfo[]) plugins.ToArray(typeof(PluginInf...
}
/// <summary>
/// プラグインクラスのインスタンスを作成する
/// </summary>
/// <returns>プラグインクラスのインスタンス</returns>
public Plugin.IPlugin CreateInstance()
{
try
{
//アセンブリを読み込む
System.Reflection.Assembly asm =
System.Reflection.Assembly.LoadFrom(this.Location);
//クラス名からインスタンスを作成する
return (Plugin.IPlugin)
asm.CreateInstance(this.ClassName);
}
catch
{
return null;
}
}
}
}
}}
FindPluginsメソッドが多少複雑ですので、簡単に説明しておき...
ここまで来たら、後は簡単です。PluginInfoクラスを使ったメ...
#code(vbnet){{
Imports System
Namespace MainApplication
Public Class PluginHost
'/ <summary>
'/ エントリポイント
'/ </summary>
<STAThread()> _
Public Shared Sub Main()
'インストールされているプラグインを調べる
Dim pis As PluginInfo() = PluginInfo.FindPlug...
'すべてのプラグインクラスのインスタンスを作成...
Dim plugins(pis.Length - 1) As Plugin.IPlugin
Dim i As Integer
For i = 0 To plugins.Length - 1
plugins(i) = pis(i).CreateInstance()
Next i
'有効なプラグインを表示し、使用するプラグイン...
Dim number As Integer = -1
Do
For i = 0 To plugins.Length - 1
Console.WriteLine("{0}:{1}", i, plugi...
Next i
Console.WriteLine( _
"使用するプラグインの番号を入力してく...
Try
number = Integer.Parse(Console.ReadLi...
Catch
End Try
Loop While number < 0 Or number >= pis.Length
Console.WriteLine(plugins(number).Name + " を...
'プラグインに渡す文字列の入力を促す
Console.WriteLine("文字列を入力してください。...
Dim str As String = Console.ReadLine()
'プラグインのRunメソッドを呼び出して結果を取...
Dim result As String = plugins(number).Run(str)
'結果の表示
Console.WriteLine("結果:")
Console.WriteLine(result)
Console.ReadLine()
End Sub
End Class
End Namespace
}}
#code(csharp){{
using System;
namespace MainApplication
{
public class PluginHost
{
/// <summary>
/// エントリポイント
/// </summary>
[STAThread]
static void Main(string[] args)
{
//インストールされているプラグインを調べる
PluginInfo[] pis = Plugin.PluginInfo.FindPlugins();
//すべてのプラグインクラスのインスタンスを作成する
Plugin.IPlugin[] plugins = new Plugin.IPlugin[pis.Leng...
for (int i = 0; i < plugins.Length; i++)
plugins[i] = pis[i].CreateInstance();
//有効なプラグインを表示し、使用するプラグインを選ばせる
int number = -1;
do
{
for (int i = 0; i < plugins.Length; i++)
Console.WriteLine("{0}:{1}", i, plugins[i].Name);
Console.WriteLine(
"使用するプラグインの番号を入力してください。:");
try
{
number = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("数字を入力してください。");
}
} while (number < 0 || number >= pis.Length);
Console.WriteLine(plugins[number].Name + " を使用しま...
//プラグインに渡す文字列の入力を促す
Console.WriteLine("文字列を入力してください。:");
string str = Console.ReadLine();
//プラグインのRunメソッドを呼び出して結果を取得する
string result = plugins[number].Run(str);
//結果の表示
Console.WriteLine("結果:");
Console.WriteLine(result);
Console.ReadLine();
}
}
}
}}
メインアプリ実行前に実行ファイルのあるフォルダに"plugins"...
基本的なプラグイン機能の実現方法は以上です。しかしより高...
この方法については、次回、Windowsアプリケーションを例に紹...
**コメント [#w1acf1e8]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-08-16 (月) 06:00:00,DOB...
ページ名:
▲
▼
[
トップ
] [
新規
|
子ページ作成
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]