MEF枚举出口和建筑 [英] mef enum exports and architecture

查看:185
本文介绍了MEF枚举出口和建筑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用我的MEF插件子系统进行,但我有几个问题,因为我在CSHARP和MEF新手(

I want to make my plugin subsystem using mef but i have few question because i am newbie in csharp and mef (

我想要做的:


  1. 每一个插件可以创建自己的界面IPlugin1,IPlugin2 ...

  2. 每个接口都必须有特定功能加载,卸载

  3. 使用MEF我想枚举所有出口,并呼吁加载/卸载

该问题:

一个。是我的解决方案很好的,如果没有我怎样才能改善它(通过使用别的东西)?

a. Is my solution good and if no how can i improve it (by using something else)?

乙。如何使用MEF来枚举所有出口,并调用指定的接口函数?

b. How to enum all exports using mef and call specified interface function?

我会为所有的链接和评论家AP preciate。感谢所有。

I would appreciate for all links and critics. Thanks for all.

推荐答案

大厦@米-Y的回答,我认为有一个共同的接口你可以去最好的设计。它是利用一组常用的操作,你可以应用到你的插件的最简单方法。我会考虑的,虽然是轻微的细化:

Building on @m-y's answer, I do think having a common interface is the best design you can go with. It is the easiest way to leverage a common set of operations you could apply to your plugins. What I would consider though, is a slight refinement:

public interface IPlugin : IDisposable
{
    void Initialise();
}

通过强制执行的Dispose 方法的实现,你的一部分可以自动由 CompositionContainer中。所有的卸载的code能在那里去,这里是一个示例插件:

By enforcing the Dispose method is implemented, you part can automatically be controlled by the lifetime management features of the CompositionContainer. All your unloading code can go in there, here is a sample plugin:

public interface ILogger : IPlugin
{
    void Log(string message);
}

[Export(typeof(ILogger))]
public class ConsoleLogger : ILogger
{
    void IPlugin.Initialise()
    {
        Console.WriteLine("Initialising plugin...");
    }

    public void Log(string message)
    {
        Console.WriteLine(message);
    }

    public virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            Console.WriteLine("Disposing plugin...");
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

的Dispose 模式允许清理你的code的标准化机制。你的 CompositionContainer中实例将继续跟踪该项目,并将其放置在清理。

The Dispose pattern allows a standardised mechanism for cleaning up your code. Your CompositionContainer instance will keep track of this item, and clean it up when it is disposed.

现在,我想描述是一个很好的补充在 MEFContrib 称为InterceptingCatalog。这是什么目录允许你这样做,是注册拦截策略,这可能给你访问一个导出值,则返回到您的电话code之前。一个这样的应用可以是自动确保初始化被称为基础上 IPlugin 接口,当实例被导出第一次:

Now, what I wanted to describe is a nice addition in MEFContrib called the InterceptingCatalog. What this catalog allows you to do, is register interception strategies which could give you access to an exported value before it is returned to your calling code. One such use could be to automatically ensure that Initialise is called on the base IPlugin interface when the instance is being exported for the first time:

public class InitialisePluginStrategy : IExportedValueInterceptor
{
    public object Intercept(object value)
    {
        var plugin = value as IPlugin;
        if (plugin != null)
            plugin.Initialise();

        return value;
    }
}

让我们配合这一切了:

Let's tie all this up:

static void Main(string[] args)
{
    var catalog = new AssemblyCatalog(typeof(Program).Assembly);

    var configuration = new InterceptionConfiguration()
        .AddInterceptor(new InitialisePluginStrategy());

    var interceptingCatalog = new InterceptingCatalog(catalog, configuration);

    var container = new CompositionContainer(interceptingCatalog);

    var logger = container.GetExportedValue<ILogger>();

    logger.Log("test");

    Console.ReadKey();
}

如果您运行,你会发现我们的 ConsoleLogger 自动初始化我们第一次从容器中得到它。我们并不需要担心它再次被初始化,只会做,当它的创建的导出的情况下,这意味着它服从单和非单的情况。

If you run that, you'll notice our ConsoleLogger is automatically initialised the first time we get it from the container. We don't need to worry about it being initialised again, it will only do so when it is creating the exported instance, which means it obeys singleton and non-singleton scenarios.

您可能会在这一点上,这可能是矫枉过正,但它实际上是相当优雅的解决方案,使您的零件自动启动,并设置不再需要时的思考。

You might be thinking at this point that this could be overkill, but its actually quite an elegant solution to enable your parts to be automatically started, and disposed of when no longer needed.

当然,如果你想在你的零件如何初始化细粒度控制,你可以只在你自己写的方法管理这些,你只需要在这样做时要考虑的插件状态。

Of course, if you want fine grained control over how your parts are initialised, you could just manage these in a method you write yourself, you just need to consider the plugin state when you do so.

您可以了解更多InterceptingCatalog在彼得Włodek的博客

You can read up about the InterceptingCatalog more at Piotr Włodek's blog

这篇关于MEF枚举出口和建筑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆