插件主要是提供可拓展点,其实现实中的需求的插件所要实现的好像也只是拓展操作之前或者操作之后,有点像AOP,那如果程序能提供这些拓展点,插件功能就可以基本实现了!代码实现思路如下:
{
public class ArticleReadingArg : EventArgs
{
public Article TheArticle { get ; set ;}
}
public class ArticlePage : System.Web.UI.Page
{
public static event EventHandler < ArticleReadingArg > OnReading;
protected override void OnInit(EventArgs e)
{
if (OnReading != null )
{
OnReading(EventArgs.Empty, new ArticleReadingArg(GetArticle(WebRequest.GetValue( " ID " ))));
}
base .OnInit(e);
}
}
首先是提供一个拓展点,假设我们要实现新闻管理系统的新闻访问统计插件,那我们要先提供一个可拓展点 代码如下这是一个页面的基类,他曝露出了一个静态的事件OnReading提供拓展者订阅页面浏览前的事件,当然,其实Page类也有很多事件可以订阅,不过并没有公开给其他类订阅或调用。好了,弄好这一步,基本条件已经成熟啦,因为外部类可以订阅到Onreading这个事件,并且可以时间的参数是可以访问到相对应的新闻实体,控制权就转移到订阅者手中了。
{
static CounterPlug()
{
if ( this .Enable)ArticlePage.OnReading += AddCount;
}
public static void AddCount( object sender, ArticleReadingArg e)
{
e.TheArticle.Hit += 1 ;
}
}
如果你用的asp.net模型是WebSite模型,那么很方便,利用本身带来的动态编译,可以很方便得实现后续的使用和管理,如果不是,可以编译成独立的dll,再利用反射创建实例,这里利用了.net静态初始化函数的特点-只在该类型的某个静态成员第一次被访问或该类型第一次实例化时执行,具体请查看msdn。我们这里用创建实例的形式激活这个静态函数,以达到事件的订阅。我们注意到插件加载是有条件的,这个条件可以根据配置文件,也可以根据数据库数据获取。下面是激活的简单代码,也就是你点击启用之后执行的
因为创建了一个实例,所以静态函数执行了,事件也被订阅了!所以插件的功能就会执行!
静态变量的生命周期是随着应用程序的结束而结束的,所以应该不会冒冒然就消失了的。好啦,到这里就实现了插件的启用了,插件的卸载也挺取巧的,本来想到应用程序域这个概念,想想还是不妥,这玩意要一定的信任级别,最后想到webConfig每次修改都会重启应用程序,嘻嘻,这个本来很讨厌的特性,在这里还有得用,关闭插件时修改配置记录问Disenable之外,修改下WebConfig的最后修改时间
System.IO.File.SetLastAccessTimeUtc(configFile,DateTime.UtcNow);