这个答案将特定于我的容器。
我们当前的应用程序需要开始支持在编译时应用程序未知的不同“插件”/“扩展”的动态加载和“挂钩”。
为了能够做到这一点,您必须定义一些您放置在类库中的扩展接口,这些接口将在您的应用程序和所有插件之间共享。
例如,如果您希望您的应用程序能够向应用程序菜单添加内容,您可以创建以下界面:
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>
插件本身提供注册方法来进行注册是否常见?
是的。通过在共享程序集中定义为扩展点的不同接口。
国际奥委会应该注册吗?(通常是怎么做的?)
是的。如果容器提供它。
使用 IoC 容器时如何轻松定义扩展点?
您可以在此处更详细地了解它:http: //www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container