【IT168技术文档】
最近要做一个应用程序检测程序,就是要检测服务器上各应用程序的运行情况,由于各应用程序的差异,很难做一个统一的探测程序,于是决定对任意一个应用程序都采用独立的一条探测规则。
为了开发、部署的方便,考虑使用插件式开发。
本文案例包含三个项目:
1) Tristan.DetectContract
插件接口(契约),定义了探测的行为,以及传递的参数
2) Tristan.DetectCenter
探测主程序,引用Tristan.DetectContract
3) CompareSvcDetector
插件1,用于探测一个名为"CompareSvc"的应用程序的插件,引用 Tristan.DetectContract
插件接口 IDetector using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tristan.DetectContract { public interface IDetector { /**//// <summary> /// 线程控制开关 /// </summary> bool ThreadFlag { get; set; } /**//// <summary> /// 探测 /// </summary> /// <param name="onNormal"></param> /// <param name="onError"></param> void Detector(Action<DetectEventArgs> onNormal, Action<DetectEventArgs> onError); } } DetectEventArgs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tristan.DetectContract { public class DetectEventArgs { /**//// <summary> /// 探测结果 /// </summary> public DetectResult DetectResult { get; set; } /**//// <summary> /// 探测任务编码 /// </summary> public string DetectCode { get; set; } /**//// <summary> /// 提示信息 /// </summary> public string Message { get; set; } } public enum DetectResult { Normal, Error } } 探测程序 using System.Linq; using System.Text; using System.IO; using System.Reflection; using Tristan.DetectContract; namespace Tristan.DetectCenter { class Program { static void Main(string[] args) { //从指定文件夹读取dll string[] files = Directory.GetFiles("PlugIn", "*.dll"); foreach (var f in files) { //通过反射加载程序集 Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + f); //获取程序集内定义的类 Type[] types = assembly.GetTypes(); foreach (Type t in types) { //判断类 t 是否实现了 IDetector接口 IDetector d = Activator.CreateInstance(t) as IDetector; if (d != null) { //置探测线程开关 d.ThreadFlag = true; //开始探测 d.Detector(new Action<DetectEventArgs>(SucceedHandler), new Action<DetectEventArgs>(ErrorHandler)); } } } Console.Read(); } static void SucceedHandler(DetectEventArgs e) { Console.WriteLine(e.DetectCode + "," + e.DetectResult.ToString() + "," + e.Message); } static void ErrorHandler(DetectEventArgs e) { Console.WriteLine(e.DetectCode + "," + e.DetectResult.ToString() + "," + e.Message); } } } 插件1 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Tristan.DetectContract; namespace CompareSvcDetector { public class CompareSvcDetector : IDetector { private string detectCode = "XX0001"; IDetector Members#region IDetector Members public bool ThreadFlag { get; set; } public void Detector(Action<DetectEventArgs> onNormal, Action<DetectEventArgs> onError) { ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o) { while (ThreadFlag) { Random r = new Random(); int i = r.Next(10); if (i < 5) { onNormal(new DetectEventArgs() { DetectResult = DetectResult.Normal, DetectCode = detectCode, Message = i.ToString() }); } if (i >= 5) { onError(new DetectEventArgs() { DetectResult = DetectResult.Error, DetectCode = detectCode, Message = i.ToString() }); } Thread.Sleep(2000); } })); } #endregion } }