Dynamic Plugins Manager (三) Demo

196 views 三月 29, 08 by Timothy

下面来演示一下Plugins Manager,先看看我们事先做好的Interface和两个具体实现的插件.

Interface,接口定义:
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Component
{
public interface IComponent
{
string Invoke();
}
}
[/code]

整个接口,只声明了一个Invoke方法,这也是具体的插件必须实现的一个方法。

第一个插件类 class1.cs
[code]
namespace Component
{

public class Class1 : MarshalByRefObject,IComponent
{
string message = string.Empty;
int number;
float number2;

public Class1(string input, int num)
{
message = input;
number = num;
number2 = 0;
}

public Class1(int num1, float num2)
{
message = "none";
number = num1;
number2 = num2;
}

public string Invoke()
{
return "This is TestLibrary. member---message:" + message + "number:" + number.ToString() + "number2:" +number2.ToString();
}
}
}

[/code]

第二个插件类 class2.cs
[code]
namespace Component
{
public class Class2 : MarshalByRefObject,IComponent
{
public Class2()
{
}

public string Invoke()
{
return "This is TestLibrary2 without construct param";
}
}
}

[/code]

这里我们看到区别,第一个插件,需要构造函数,第二个插件不需要构造函数,所以在配置文件中,第二个插件可以关闭掉ConstructParam这个节点。

下面我们将Class1.cs编译好,放到插件目录中,改名为TestLibrary.dll,将Class2.cs直接改名为TestLibrary2.cs,放到插件目录中。
演示的目的:插件1需要在加载时,构造初始化函数,而插件2不需要。
插件1,是已经编译好的dll,不需要实时编译,但是插件2需要。

下面是测试的截图

1.插件目录,一个放入编译好的dll,一个放入.cs源码

2.启动测试程序,看到2个插件都已经被加载

3.此时,再查看插件的目录,我们会看到Plugin Manager为我们编译,并生成的插件2的dll

4.查看插件的日志记录

5.插件的调用
选中TestLibrary,点击Invoke按钮:

选中TestLibrary2,点击Invoke按钮:

6.插件的动态卸载和发布
a.动态卸载,可以直接使用Plugins Manager的UnloadPluginByName直接通过程序调用卸载。也可以手动打开插件的配置文件,将EnablePlugin设置为False
b.动态发布,直接在插件目录中,建立一个新的子目录,然后将插件的dll和xml配置文件直接拷入即可
关于第6点,这些功能的演示,截图比较麻烦,大家可以直接使用测试程序测试即可。



随机日志

Add your comment

6 Responses to "Dynamic Plugins Manager (三) Demo"

  1. haroun CHINA 说:

    想问下,如果是有界面的插件,能不能加载呢?比如我是以多窗体为形式,每一个子窗体就为一个插件,那要怎么做呢?据我所知,appdomain是不支持界面的吧?
    [reply=cooldog,2009-03-05 11:35 AM]haroun 有界面的当然也可以。其实是否支持界面和AppDomain没有什么联系。你可以把WinForm的界面和代码封装在插件的dll里面,在调用插件方法的时候,创建这个Form就可以了。如果你需要的话,我可以提供代码。[/reply]

  2. haroun CHINA 说:

    如果你可以提供代码最好啦,我就是想不出来。我也试着玩了一下,最后只能用一个域来加载dll,创建实例,然后作为主窗体的子窗体加进去。但是用一个域来加载的话,就不能卸载了,这好郁闷哦。不知你有什么好方法,期待你的代码,呵……。

    另外还有一件好郁闷的事,就是发现界面好容易假死在那里,即使我用了多线程也一样,只要访问服务。有什么办法不让它假死在那里呢?

    cooldog,先谢谢你哦。今天在在你的blog里转了一天,学了不少东西,呵。

    还有,我的邮箱是chenhuizhong_n@163.com。或者你就写一个例子是可以加载界面插件的,提供源码下载,让我们大家都学习一下。我也从那里下载就行了!

    [reply=cooldog,2009-03-06 09:50 AM]用域的方式当然是可以卸载的……实例的代码我发到你邮箱了。[/reply]
    [reply=cooldog,2009-03-06 09:58 AM]另外还有一件好郁闷的事,就是发现界面好容易假死在那里,即使我用了多线程也一样,只要访问服务。有什么办法不让它假死在那里呢?
    ———————————————————————————–
    这个要看你访问的服务是什么服务?是WebService一类的吗?访问这类服务其实有几种方式,你用的估计是默认的同步方式,同步方式必须要等待调用完毕,界面线程才恢复响应,继续执行。可以考虑采用异步的方式,这样界面就不会出现你说的假死现象了。[/reply]

  3. haroun CHINA 说:

    你发给我的代码已收到,先研究一下。谢谢哦。

  4. haroun CHINA 说:

    另外还有一个问题想问下你,我做了一个程序,老是在跑着跑着的时候(或者狂点界面操作-不访问服务)就会si在那里,然后从任务管理器看到该程序的线程在猛增,估计是出现什么si锁之类的吧。但是它却不报错,所以不知在那里出现问题了。有什么办法可以检测一下呢?

  5. haroun CHINA 说:

    那个假si的问题,情况是这样的,因为界面要处理显示的数据,所以用了C O N T R O L.B E G IN INVOKE()的方法,我本想做一个进度条在那里的,但是界面停在那里,进度条自然也不能动了。
    [reply=cooldog,2009-03-06 03:15 PM]这估计要看看具体的代码才知道了……[/reply]

  6. haroun CHINA 说:

    cooldog,你好!
    你那插件的例子,我已经看了。但是我要的效果不是这样子的,我要的不是子域操作子域内的窗体,我是想把子域里的窗体返回给主域,让主域可控制。比如多窗体那样子,主窗体就是主域(就是插件管理器),而子窗体就是一个子域(就是插件)。不知这样行不行?


Leave a Reply

(Ctrl+Enter)