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

- システム
エンジニア - C#の開発をしていて、同じクラスを毎回記述するのが面倒なのですが、何かいい方法はないですか。
- プロジェクト
マネージャー - そういう場合は、プラグインを作成して使うことをおススメします。
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を記述するとどうなるのでしょうか。
その場合は同じ名前・内容の別のインターフェイス扱いになってしまいます。面倒ですがインターフェイス用のプラグインを作って参照する必要があるのです。
- システム
エンジニア - 複数のプロジェクトで同じクラスを使うにはプラグインを作っておけばいいのですね。
- プロジェクト
マネージャー - そのとおりです。解説した内容を理解して、プラグインを作ってみてください。
C#のプラグインはこんなに簡単に使える
C#のプラグインの使い方について解説しましたがご理解頂けましたでしょうか。
静的参照はとても簡単に使えますが、動的参照は少し面倒になります。それでも安全性を優先すべきなので、このやり方で動的参照を行ってください。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社夢真ビーネックスグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅)システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅)デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅)デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅)基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅)基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)