.net column
.NET開発者のためのブログメディア

C#でプラグインを作る方法を解説します

2020年08月25日
SE
C#の開発をしていて、同じクラスを毎回記述するのが面倒なのですが、何かいい方法はないですか。
PM
そういう場合は、プラグインを作成して使うことをおススメします。

C#のプラグインとは


C#の開発をしていて、複数のプロジェクトで共通して使用するクラスを毎回同じように記述せず、独立した別のファイルにして使い回したいと思うことがあるはずです。そういったファイルをプラグイン、またはライブラリと呼びます。

プラグインを使うのは難しそうに感じるもしれませんが、実は意外と簡単です。この記事でVisual StudioでC#のプラグインを作成する手順を分かりやすく解説するので、是非ご覧ください。

C#のプラグインのシンプルな例

まずはVisual StudioでC#のクラスライブラリのプロジェクト「TestClassLibrary」を作成してください。そして以下のように記述しましょう。

namespace TestClassLibrary
{
public class AddTwoValues
{
public int Value1
{
get; set;
}
public int Value2
{
get; set;
}
public int Sum()
{
return Value1 + Value2;
}
}
}

dllファイルをプラグインとして使用する

2つの値を渡してそれの合計を出してくれるプラグインを複数のプロジェクトで使いたい、という時にこのAddTwoValuesを利用するとします。実際にそんな単純な機能のプラグインが必要なケースはないでしょうが、あくまでサンプルということです。

これをビルドすると、「C:\Users\(ユーザー名)\source\repos\TestClassLibrary\TestClassLibrary\bin\Debug\netstandard2.0」にTestClassLibrary.dllが作成されますが、これをプラグインとして利用できます(パスは開発環境により若干違うかもしれません)。

プラグインを静的に使用する方法

作成したプラグインのTestClassLibraryを静的に使用しましょう。静的とはプラグインをビルドする時点で組み込むことです。Visual Studioで、プラグインを実際に使用する別のC#プロジェクトを作成しましょう。

そしてソリューションエクスプローラーの「依存関係」をクリックして「COM参照を追加」を選択してください。次に参照マネージャーの右下にある「参照(B)」ボタンを押して、TestClassLibrary.dllを選択します。これでプロジェクトにプラグインが静的に組み込まれました。

静的なプラグインの利用方法はとても簡単

これでプラグインのAddTwoValuesクラスを使えるようになります。以下のようにC#で記述して実行してみましょう。

TestClassLibrary.AddTwoValues atv = new TestClassLibrary.AddTwoValues();
atv.Value1 = 5;
atv.Value2 = 3;
Console.WriteLine(atv.Sum());

結果は8が表示されます。このようにプラグインを静的に使用するのは簡単です。

プラグインを動的に使用する方法

次はプラグインを動的に使用する方法を解説します。動的とは、静的な方法の様にビルドする時に組み込むのではなく、実行中にプラグインを参照して使用するという方法です。以下がそのC#サンプルです。

なお先頭には「using System.Reflection」を記述してください。LoadFromのパラメータにはdllがある場所を記述してください。依存関係に先ほどのdllへの参照設定がある場合は、それを削除してから実行します。

var asm = Assembly.LoadFrom(@”C:\~~~\TestClassLibrary.dll”);
var classType = asm.GetType(“TestClassLibrary.AddTwoValues”);
dynamic atv = Activator.CreateInstance(classType);
atv.Value1 = 7;
atv.Value2 = 2;
Console.WriteLine(atv.Sum());

動的参照はとても遅い

これを実行すると9が表示されます。サンプルの解説すると、まずAssembly.LoadFromでdllファイルを読み込みます。そしてGetTypeによりプラグインのクラス情報を取得し、CreateInstanceでAddTwoValuesをdynamicとして生成しています。後は通常通り使用できます。

これを実行すると分かるのですが、読み込みにかなり時間がかかります。一度読み込めば後は速くなるのですが、プラグインの動的参照はパフォーマンスを重視する場合は避けて、静的に行った方が良いですね。

dynamicで生成するとクラスの情報はわからない

動的参照の問題点は遅いこと以外に、危険性が高いということもあります。dynamicは動的型付けを可能にしますが、プログラムしている時点ではクラスの情報がわかっていません。

このC#サンプルでいえば、ビルド時はValue1・Value2というプロパティとSumというメソッドが本当にあるかどうかは不明です。

もしそれらのプロパティやメソッドの名前の呼び出しが間違っていると、実行時に以下のような例外が発生してしまいます。

Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ‘TestClassLibrary.AddTwoValues’ does not contain a definition for ‘Value3’

インターフェイスで動的参照の問題を解決

この動的参照の問題を解決する方法は、インターフェイス専用のプラグインを作ることです。新しいC#のクラスライブラリのプロジェクトを作成して、以下のインターフェイス(interface)を記述してビルドします。クラス(class)ではない点に注意してください。

namespace IAddTwoValues
{
public interface IAddTwoValues
{
int Value1
{
get; set;
}
int Value2
{
get; set;
}
int Sum();
}
}

プラグインにインターフェイスを実装する

そしてTestClassLibraryのプロジェクトに切り替えて、ソリューションエクスプローラーで依存関係に先ほどのIAddTwoValues.dllを追加します。次にクラス宣言の箇所を以下のように修正してインターフェイスを実装します。

public class AddTwoValues : IAddTwoValues.IAddTwoValues

IAddTwoValuesインターフェイスによって、AddTwoValuesはValue1・Value2・Sumを持つことを強制されます。試しにそれぞれのプロパティやメソッドの名前を変えてみてください。エラーとなります。

asを使用してインターフェイスを実装するインスタンスとして生成

次にプラグインを実際に使用するプロジェクトに切り替えて、こちらにもソリューションエクスプローラーの依存関係にIAddTwoValues.dllを追加します。そしてC#のプログラムを以下のように修正しましょう。

var asm = Assembly.LoadFrom(@”C:\~~~\TestClassLibrary.dll”);
var classType = asm.GetType(“TestClassLibrary.AddTwoValues”);
IAddTwoValues.IAddTwoValues atv = Activator.CreateInstance(classType) as IAddTwoValues.IAddTwoValues;

if (atv != null)
{
atv.Value1 = 7;
atv.Value2 = 2;
Console.WriteLine(atv.Sum());
}
else
{
Console.WriteLine(“IAddTwoValuesインターフェイスを実装していません。”);
}

インターフェイスを使えば動的参照が安全になる

以前との変更点は、CreateInstanceする時にasを使用してIAddTwoValuesを実装するクラスとしてインスタンスを生成しているのと、生成に失敗した時はプラグインがIAddTwoValuesを実装していないと判断するようにしたことです。

これにより安全なプログラムになりましたね。Value1・Value2・Sumを別の名前にすればエラーになりますし、プラグインにそれらが無ければ実行しないようにしています。これこそがinterfaceの本来の使い方なのです。

なおIAddTwoValues.dllを作らずに、プラグインとそれを利用するプロジェクトに全く同じIAddTwoValuesを記述するとどうなるのでしょうか。

その場合は同じ名前・内容の別のインターフェイス扱いになってしまいます。面倒ですがインターフェイス用のプラグインを作って参照する必要があるのです。

SE
複数のプロジェクトで同じクラスを使うにはプラグインを作っておけばいいのですね。
PM
そのとおりです。解説した内容を理解して、プラグインを作ってみてください。

C#のプラグインはこんなに簡単に使える

C#のプラグインの使い方について解説しましたがご理解頂けましたでしょうか。

静的参照はとても簡単に使えますが、動的参照は少し面倒になります。それでも安全性を優先すべきなので、このやり方で動的参照を行ってください。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)

Search

Popular

reccomended

Categories

Tags

Jobs