使用MEF用C#,我怎么调用主机上的方法,从插件? [英] Using MEF with C#, how do I call methods on the host, from the plugin?

查看:235
本文介绍了使用MEF用C#,我怎么调用主机上的方法,从插件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用href=\"http://mef.codeplex.com/\" rel=\"nofollow\">托管扩展性框架(MEF)框架

这是工作的罚款,我可以致电/从插件的交互主应用程序。不过,我也希望能够从的插件宿主应用程序的互动,但似乎无法找出如何做到这一点。



我希望能够得到/设置/从我的插件主要的应用程序执行导出的属性和方法。目前,我只能够说话,从主应用程序,而不是周围的其他方法,以及插件



我的代码迄今:



接口DLL

 命名空间MefContracts 
{
[InheritedExport]
公共接口IPlugin
{
字符串的DoWork();
}

公共类的Class1
{
公共IPlugin插件{搞定;组; }
}
}

主要/主机应用程序

 命名空间MyMEF 
{
类clsMEF
{
私人CompositionContainer中_container ;

[导入(typeof运算(MefContracts.IPlugin))]
公共MefContracts.IPlugin插件;

公共clsMEF()
{
撰写();
}

无效撰写()
{
变种目录=新AggregateCatalog();
catalog.Catalogs.Add(新DirectoryCatalog(.. \\..\\Extensions));
_container =新CompositionContainer中(目录);

{
this._container.ComposeParts(本);
}
赶上(CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
}
}

无效的主要()
{
clsMEF myMef =新clsMEF();
MessageBox.Show(myMef.plugin.DoWork());
}
}



插件

 命名空间MefPlugin 
{
[导出]
公共类的Class1:MefContracts.IPlugin
{

公共字符串的DoWork()
{
返回插件叫做;
}
}
}


解决方案

在太多的出场和反复试验,我发现我有在我还没有加入当前执行的程序集的问题( System.Reflection.Assembly.GetExecutingAssembly())到主机的装配与插件的组件沿目录



非常感谢@PanosRontogiannis谁得到我的行权 - 这个问题的答案工作出色,一旦装配是正确。添加



下面是对别人有需要的工作代码:



接口DLL

 使用System.ComponentModel.Composition; 

命名空间MefContracts
{
[InheritedExport]
公共接口IPlugin
{
字符串的工作(字符串输入);
}

[InheritedExport]
公共接口IHost
{
字符串版本{搞定; }
}
}



宿主应用程序

 使用System.ComponentModel.Composition; 
使用System.ComponentModel.Composition.Hosting;

命名空间MyMEF
{

[导出]
公共类的Class1:MefContracts.IHost
{
公共字符串版本
{
{返回V1.00 }
}
}

类clsMEF
{
私人CompositionContainer中_container;

[导入(typeof运算(MefContracts.IPlugin))]
公共MefContracts.IPlugin插件;

公共clsMEF()
{
撰写();
}

无效撰写()
{
变种目录=新AggregateCatalog();
catalog.Catalogs.Add(新DirectoryCatalog(.. \\..\\Extensions));
catalog.Catalogs.Add(新AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); //< - 这是一块失踪
_container =新CompositionContainer中(目录);

{
this._container.ComposeParts(本);
}
赶上(CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}

}
}
静态类节目
{
静态无效的主要()
{
clsMEF myMef =新clsMEF();
MessageBox.Show(myMef.plugin.Work(我输入));
}
}
}



插件

 使用System.ComponentModel.Composition; 

命名空间MefPlugin
{
[导出]
公共类Class2中:MefContracts.IPlugin
{
[导入(typeof运算(MefContracts.IHost ))]
公共MefContracts.IHost主机;

公共字符串的工作(字符串输入)
{
返回插件调用(输入:+输入+)主机应用程序版本:+输入+ Host.Version;
}
}
}


I am trying to add plugin extensibility to my C# application using the Managed Extensibility Framework (MEF) framework, and so far it is going ok; I have my main/host application loading plugins from a defined folder, and can call their methods etc. from the main application. Both the host application and the plugins reference a seperate dll assembly which contains the interfaces common to all projects.

This is working fine and I can call/interact with the plugins from the main application. However, I also would like to be able to interact with the host application from the plugins, but can't seem to find out how this is done.

I would like to be able to get/set/execute exported properties and methods in the main app from my plugins. Currently I am only able to 'speak' to the plugins from the main app, not the other way around as well.

My code thus far:

Interface DLL

namespace MefContracts
{
    [InheritedExport]
    public interface IPlugin
    {
        String DoWork();
    }

    public class Class1
    {
        public IPlugin plugin { get; set; }
    }
}

Main/Host Application

namespace MyMEF
{
    class clsMEF
    {
        private CompositionContainer _container;

        [Import(typeof(MefContracts.IPlugin))]
        public MefContracts.IPlugin plugin;

        public clsMEF()
        {
            Compose();
        }

        void Compose()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog("..\\..\\Extensions"));
            _container = new CompositionContainer(catalog);
            try
            {
                this._container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }
        }
    }

    void Main()
    {
        clsMEF myMef = new clsMEF();
        MessageBox.Show(myMef.plugin.DoWork());
    }
}

Plugin

namespace MefPlugin
{
    [Export]
    public class Class1 : MefContracts.IPlugin
    {

        public String DoWork()
        {
            return "Plugin called";
        }
    }
}

解决方案

After much playing and trial and error, I found the issue I was having was I had not added the current executing assembly (System.Reflection.Assembly.GetExecutingAssembly()) to the host's assembly catalogue along with the plugin's assemblies.

Many thanks to @PanosRontogiannis who got me on the right lines - that answer worked brilliantly once the assembly was properly added.

Here is the working code for others in need:

Interface DLL

using System.ComponentModel.Composition;

namespace MefContracts
{
    [InheritedExport]
    public interface IPlugin
    {
        String Work(String input);
    }

    [InheritedExport]
    public interface IHost
    {
        string Version { get; }
    }
}

Host Application

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MyMEF
{

    [Export]
    public class Class1 : MefContracts.IHost
    {
        public String Version
        {
            get { return "v1.00"; }
        }
    }

    class clsMEF
    {
        private CompositionContainer _container;

        [Import(typeof(MefContracts.IPlugin))]
        public MefContracts.IPlugin plugin;

        public clsMEF()
        {
            Compose();
        }

        void Compose()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog("..\\..\\Extensions"));
            catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); // <-- THIS WAS THE MISSING PIECE
            _container = new CompositionContainer(catalog);
            try
            {
                this._container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }

        }
    }
    static class Program
    {
        static void Main()
        {
            clsMEF myMef = new clsMEF();
            MessageBox.Show(myMef.plugin.Work("My Input"));
        }
    }
}

Plugin

using System.ComponentModel.Composition;

namespace MefPlugin
{
    [Export]
    public class Class2 : MefContracts.IPlugin
    {
        [Import(typeof(MefContracts.IHost))]
        public MefContracts.IHost Host;

        public String Work(String input)
        {
            return "Plugin Called (Input: " + input + "). Host Application Version: " + input + Host.Version;
        }
    }
}

这篇关于使用MEF用C#,我怎么调用主机上的方法,从插件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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