好了,我有一个.净项目使用的插件。插件是实现为类库(DLL)项目,每个建立在他们自己的文件夹。主要的项目不需要插件Dll运行,但如果它们是可用的,它们被用于各种可选择的功能。类的插件加载过 Type.GetType().

然而,对于我自己的目的而测试的软件,我想能够开发该软件的主要应用程序在相同的时间。我已经创建了一个"主人"的解决方案文件,该文件引用的所有项目,所以我可以断点和步骤跨大会的界限。然而,问题是,插入他们自己的目录,所以我必须以某种方式获得的插件等文件的某个地方在那里 Type.GetType() 可以找到他们。

编辑:为了澄清,我的代码中已经列举了等文件中相同的目录中。exe和发现的课程相匹配给出口(的使用 Assembly.LoadFile(), Assembly.GetExportedTypes(), , Type.IsAssignableFrom()).然后用户选择的插件启用的,我保存这些选择的数据库使用 Type.AssemblyQualifiedName.最后,当我需要使用所提供的功能,使用我 Type.GetType() 载的插件类。所有这些工作完全一样的目的。只是当我建立的程序,我得到一个副本。exe没有任何插件。我在寻找一种方法来结构的项目和方案文件,以便我可以保持的主要应用程序和插件单独的项目,同时仍然能够调试他们一起在Visual Studio.这是否有意义吗?

迄今为止,这些是我的想法有:

  • 添加提到的插件项目的主要项目.
    这具有的优点是,它将始终作为打算在我的调试环境,但这会引起问题时,我的程序是,部署没有其插件?我检查使用依赖沃克似乎没有任何直接DLL依存创建的通过该项目参考。是否有任何隐藏的问题知道的在这里吗?

  • 改变所有的插件的项目,以建立成同一个目标目录.
    这似乎是工作不够好,但它还会模糊了我的建树,这将使它更难开发只有一个项目,但不具有其他项目中选出的(现在他们都是兄弟姐妹文件夹在颠复).

  • 增加一个后建立脚本以复制的插件对另一个目录.
    这实际上是我在做什么的时刻,它工作得很好,但它似乎非常予以解决了和脆弱的。我想切换到另一种方法。

  • 找到一种方式 Type.GetType() 来搜索其他目录Dll
    这是类似于如何我会用 LD_LIBRARY_PATH 在类Unix系统。显然,我只想要使这种调试基础,因为在有释放模式,这可能会引起很多微妙的问题上的用户的系统。但是这个可能吗?如果是这样,怎么样?

有趣的是,在 这个教程 关于这个问题,它说:

要做的第一件事就是参照这类图书馆,我们刚刚创建,并设置的建造出的同一目录。

这似乎是最理想给我。是否有一个更好的办法?

有帮助吗?

解决方案

设项目使得可执行的是编制为1位置,而你的"插件"获得汇编到同一位置。你可以用路口用于制作"bin"的路径,最终位置。

还在你的插件项目所设定的可执行的调试的主机。

如果你还没有这样做,确保您的接口是没有得到重新编译的每一个编译可执行软件(如果它是强烈的命名),因为这将迫使你重新编译的每一个插件每次重新编译主exe。

其他提示

一个插件的模式,我将看一看 Activator.CreateInstanceActivator.CreateInstanceFrom 方法,甚至看一看 Assembly.LoadFrom.这些方法能让你来负荷类型组件目录中的其他比的"传统的"输出的目录(bin, debug, release).

强迫 Type.GetType 找到你的"插件"的组件是真的取决于你如何修改政策的加载程序,以搜索的组件。例如,可以设置 AppDomain.PrivateBinPath 财产改变的子目录的装载机会寻找 引用 大会。

关于第一点"添加提到的插件项目"。嗯,这将土地,一个在困难的情况下防止可扩展性的未来。如果有什么 希望产生一个新的插件?哎呦,你现在没有参照它所以我想我插件不工作然后呢?这就是为什么还会需要以另一种方法。一个我们,我们将"探测器"插件组件。

注意到
在一个插件模型,所有的插件应反对一个共同的接口(或抽象的级),它是真的 实现你寻找的任何新的插件负荷。例如:

private void LoadAllPlugins(string path)
{
    foreach(string file in Directory.GetFiles(path, "*.dll"))
    {
        Assembly a = Assembly.LoadFrom(file);
        foreach(Type t in a.GetTypes())
        {
            if (t.GetInterface("IMyPluginInterface", true))
            {
               // we now have a potential plugin type that implements required functionality
            }
        }
    }
}

最后,.净3.5支持一个插件模型(系统。AddIn),还检查了设法扩展性的框架释放从Microsoft,允许开发商建立简单 组合 插件(http://www.codeplex.com/MEF)

仅仅包括插件内的项目解决方案,但只有一个依赖关系的插件对'程序'的项目。执行这一通过保持一个复制的解决方案,但只有应用程序项目(s),并确保建立干净。你可能还需要考虑的一个后建立的步骤,试图建立的每一个插件单独项目没有其他人。

一个其他检查是如果你想要强制执行后向兼容性,或者至少知道当一个明显打破已经发生。这是最简单的如果你有一个试验项目,该项目引用的插件通过dll参考项目不参考(一个小麻烦在一个试验项目)。然后通过修改引用的道路,在该项目设置的,你可以点旧版本的插件。这样做恰当地为部分o脚本测试,也是合理简单。

我的第二项建议的使用 MEF 系统uness你的插件是有效地知道在编制的时间只是没有哪个具体版本的dll您计划在装载。

我做了一个 插件系统 一段时间以前采用的反思。该机制类似于一种使用在推我找到相当灵活的。

我有两篇文章说明: Sistema de插件con。一.单方面ConceptosSistema de插件con。Parte II。El código explicado 但我没有时间来翻译它们还(以便他们在西班牙文)。代码然而是评论说英语(如果我记忆正确的).

我会试着解释我方法这里。

基本上你有插件,因为它们通常定义、类实现一个简单的接口。该接口描述的方法,用于装载、装卸、安装、卸载和配置的插件。

然后你有两种方面的插件。

第一个插件可以提供一种服务于其他类通过实施一个公共(通称)的接口和标记本身作为一种服务通过使用"ServiceAttribute".插件系统,随后将登记的服务,并使其公开提供任何有兴趣使用它。例如:

ICrypt crypto = Plugins.Service["Crypt"] as ICrypt;
if (crypto != null)
  crypto.Crypt(data, key, etc)

在另一方面,你已经挂钩。钩子插件的事件。你有两个属性HookAttribute和HookableAttribute.

当你宣布一个方法作为Hookable你是说你期望它被截获通过其他插件。例如

[Hookable]
public event TextChanged OnTextChanged;
//.....
if (OnTextChanged != null)
  OnTextChanged(ref myText);

和在其它插件

[Hooks("OnTextChanged")]
public bool MyTextChanged(ref myText)
{
  myText = "Hello from the plugin";
  return true;
}

钩子签名(delegate)可以将未知的,只要签署相匹配。再插件系统处理比赛,并带来了它toguether.

它还包括一些属性来表达之间的依赖关系的插件和自动检测和装载和那样的事情。该项目本身是LGPL,所以你可能会发现某些想法在这或甚至更好的...做出贡献:P

顺便说一句,我使用一个插件子文件夹,在我的地方插件。我没有问题的调试他们VS只要插项目是解决方案的一部分,我的工作。我不需要引用他们或电气特性的事情,如果插件解决方案的一部分那么我能够调试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top