この回答は、私のコンテナに固有のものです。
現在のアプリケーションは、コンパイル時にアプリケーションに認識されていないさまざまな「プラグイン」/「拡張機能」の動的ロードと「フック」のサポートを開始する必要があります。
これを可能にするには、アプリケーションとすべてのプラグインの間で共有されるクラス ライブラリに配置するいくつかの拡張インターフェイスを定義する必要があります。
たとえば、アプリケーションがアプリケーション メニューに何かを追加できるようにしたい場合は、次のインターフェイスを作成できます。
class ApplicationMenu
{
// The "File" menu
IMenuItem File { get; }
}
interface IMenuRegistrar
{
void Register(ApplicationMenu menu);
}
つまり、プラグインは次のクラスを作成できます。
[Component]
public class CoolPluginMenuRegistrar : IMenuRegistrar
{
public void Register(ApplicationMenu menu)
{
menu.File.Add("mnuMyPluginMenuName", "Load jokes");
}
}
この[Component]
属性はコンテナによって使用され、クラスを検出して自動的に登録できるようにします。
上記のようなすべての拡張ポイントを登録するために必要なことは、次のとおりです。
public class Program
{
public static void Main(string[] args)
{
var registrar = new ContainerRegistrar();
registrar.RegisterComponents(Lifetime.Transient, Environment.CurrentDirectory, "MyApp.Plugin.*.dll");
var container = registrar.Build();
// all extension points have been loaded. To load all menu extensions simply do something like:
var menu = GetMainMenu();
foreach (var registrar in container.ResolveAll<IMenuRegistrar>())
{
registrar.Register(menu);
}
}
}
これらの拡張機能は、特定のクラスのイベント ハンドラーとして追加されるなど、アプリケーションのさまざまな領域に "フック" されます。私の知る限り、IoC コンテナーを使用すると、実行時にオブジェクトを動的に検出し、それらをコンテナーに登録できます。
うん。あなたはそれをすべて手に入れます。
IoC コンテナーは、さまざまなイベントにフックすることもできますか? それとも、そのようなフレームワークなしでこのタスクを実行する方が簡単ですか?
はい。イベントメカニズムが組み込まれています。イベント クラス (共有クラス ライブラリ内の通常の .NET クラス) を配置します。インターフェイスを実装することで、それらをサブスクライブするだけです。
[Component]
public class ReplyEmailNotification : ISubscriberOf<ReplyPosted>
{
ISmtpClient _client;
IUserQueries _userQueries;
public ReplyEmailNotification(ISmtpClient client, IUserQueries userQueries)
{
_client = client;
_userQueries = userQueries;
}
public void Invoke(ReplyPosted e)
{
var user = _userQueries.Get(e.PosterId);
_client.Send(new MailMessage(user.Email, "bla bla"));
}
}
イベントを公開するには:
DomainEvent.Publish(new ReplyPosted(user.Id, "This is a subject"));
イベントは、次の条件を満たしている限り、任意のプラグインで処理できます。
- イベントクラスにアクセスできます
- コンテナに登録済み(
[Component]
または手動登録)
- 道具
ISubscriberOf<T>
プラグイン自体が登録を行うための Register メソッドを提供するのは一般的ですか?
うん。共有アセンブリの拡張ポイントとして定義されているさまざまなインターフェイスを介して。
IoC が登録を行う必要がありますか? (それは通常どのように行われますか?)
はい。コンテナがそれを提供する場合。
IoC コンテナーを使用するときに拡張ポイントを簡単に定義するにはどうすればよいですか?
詳細については、http: //www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Containerを参照してください。