首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >一个小型插件系统的简单IoC容器

一个小型插件系统的简单IoC容器
EN

Stack Overflow用户
提问于 2012-09-12 13:20:51
回答 2查看 1.2K关注 0票数 5

我正在为.NET 3.5应用程序(WinForms)设计一个简单的插件框架a。

我们当前的应用程序需要开始支持不同的“插件”/“扩展”的动态加载和“挂钩”,这些插件在编译时是应用程序所不知道的。

这些扩展将被“链接”到应用程序的不同区域,例如作为特定类的事件处理程序的aded。

例如(简化):

代码语言:javascript
复制
public class SomeSystem
{
     public event Action<string> Completed;

     public event Action<string> Failed;

     public event Action<string> Stopped;
}

我想要的一个用例是,开发人员能够在插件程序集中为此类事件定义处理程序,而不让应用程序了解它们。

据我所知,IoC容器允许在运行时动态地发现对象并在容器中注册它们。

IoC容器也能为我连接到各种事件吗?或者,如果没有这样的框架,这项任务更容易完成吗?

如何设计如何为这样的任务集成IoC容器?(假设有多个扩展点,例如可以用来注册的不同事件)。

我发现自己在问一些问题:

  1. 插件本身提供了一个寄存器方法来进行注册,这很常见吗?
  2. IoC应该注册吗?(这通常是怎么做到的?)
  3. 在使用IoC容器时,如何容易地定义扩展点?
EN

回答 2

Stack Overflow用户

发布于 2012-09-12 13:27:56

您可能想看看MEF。它允许你询问的所有事情。它使用的术语(ComposableParts、Exports等)最初是令人困惑的,但使用起来非常简单。

插件本身提供了一个寄存器方法来进行注册,这很常见吗?

MEF让应用程序完成查找和注册插件的工作。这个插件只需要实现一个接口,上面写着"I是一个可以做X的插件“。

IoC应该注册吗?(这通常是怎么做到的?)

使用MEF插件的应用程序能够指定如何加载插件。这可以通过搜索DLL目录、读取程序集名称列表的配置文件、检查GAC -任何内容。它是完全可扩展的(因为您可以编写自己的搜索类)

在使用IoC容器时,如何容易地定义扩展点?

MEF使用接口来定义应用程序和插件之间的契约。

票数 5
EN

Stack Overflow用户

发布于 2012-09-12 14:56:48

这个答案将专门针对我的容器。

我们当前的应用程序需要开始支持不同的“插件”/“扩展”的动态加载和“挂钩”,这些插件在编译时是应用程序所不知道的。

要做到这一点,您必须定义一些扩展接口,这些接口放置在类库中,这些类库将在应用程序和所有插件之间共享。

例如,如果您希望您的应用程序能够向应用程序菜单添加内容,您可以创建以下接口:

代码语言:javascript
复制
class ApplicationMenu
{
    // The "File" menu
    IMenuItem File { get; }
}

interface IMenuRegistrar
{
    void Register(ApplicationMenu menu);
}

这意味着插件可以创建以下类:

代码语言:javascript
复制
[Component]
public class CoolPluginMenuRegistrar : IMenuRegistrar
{
    public void Register(ApplicationMenu menu)
    {
        menu.File.Add("mnuMyPluginMenuName", "Load jokes");
    }
}

我的容器使用了[Component]属性,以便它能够为您发现并自动注册类。

注册所有扩展点(如上面的扩展点)所需要做的就是:

代码语言:javascript
复制
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);
        }
    }
}

这些扩展将被“链接”到应用程序的不同区域,例如作为特定类的事件处理程序的aded。据我所知,IoC容器允许在运行时动态地发现对象并在容器中注册它们。

是啊。你都明白了。

IoC容器也能为我连接到各种事件吗?或者,如果没有这样的框架,这项任务更容易完成吗?

是。我有一个内置的事件机制。将事件类(共享类库中的常规.NET类)放入其中。简单地通过实现一个接口来订阅它们:

代码语言:javascript
复制
[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"));
    }
} 

并发表下列活动:

代码语言:javascript
复制
DomainEvent.Publish(new ReplyPosted(user.Id, "This is a subject"));

事件可以由任何插件处理,只要它们:

  1. 可以访问事件类。
  2. 已在容器中注册([Component]或手动注册)
  3. 实现ISubscriberOf<T>

插件本身提供了一个寄存器方法来进行注册,这很常见吗?

是啊。通过在共享程序集中定义为扩展点的不同接口。

IoC应该注册吗?(这通常是怎么做到的?)

是。如果容器提供的话。

在使用IoC容器时,如何容易地定义扩展点?

您可以在这里更详细地了解它:http://www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12389163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档