插件原理——模拟插件工作原理
本菜鸟一直好奇插件的原理,今闲暇之余就心血来潮地进行了模拟。虽不甚完美,却私感有几分道理。权且记之,以备后用。[源码备份于此]
[模拟思路]
用户从外部输入信息,然后将输入信息打印到控制台上。此过程中由一插件对数据进行拦截并修改,最终将修改后的数据进行打印。
由此可抽象出以下关系图:
需要的类:
- Message,存储用户输入的信息
View Code
/// <summary> /// A simulated data model. /// </summary> public class Message { public string Content { get; set; } }
- DisplayMessage,向屏幕打印信息
View Code
public class DisplayMessage : IPlugin, IPrinter { public void Execute(Message message) { //Can do something here, for example, data validation verification. } public void PrintMessage(Target.Message message) { Console.Write(message.Content); } }
- InterceptMessage,拦截并修改用户输入的信息
View Code
/// <summary> /// Intercept the message and change it. /// </summary> public class InterceptMessage : Target.IPlugin { public void Execute(Target.Message message) { message.Content = "The content has been changed by plugin."; } }
- Processor,注册插件事件队列并完成打印工作。
View Code
class Processor { private delegate void ExecuteHandler(Target.Message contextHandler); private event ExecuteHandler ExecuteEvent; public Processor(Target.Message message) { //Initializes the event queue. InitializeExecuteEvent(); //Invoke execute events queue. ExecuteEvent.Invoke(message); //Display the message. Target.IPrinter printer = new Target.DisplayMessage(); printer.PrintMessage(message); } /// <summary> /// Initializes the execute event queue. /// </summary> private void InitializeExecuteEvent() { Dictionary<string, string> types = RegisterTypes(); foreach (KeyValuePair<string, string> type in types) { Target.IPlugin intercept = GetInstance<Target.IPlugin>(type.Key, type.Value); //Register event queue. ExecuteEvent += new ExecuteHandler(intercept.Execute); } } /// <summary> /// Get a instance of spcificed type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="assemblyName"></param> /// <param name="typeName"></param> /// <returns></returns> private T GetInstance<T>(string assemblyName, string typeName) { return (T)Assembly.Load(assemblyName).CreateInstance(typeName); } /// <summary> /// Register types.(Usually stroed in config file.) /// </summary> /// <returns></returns> private Dictionary<string, string> RegisterTypes() { Dictionary<string, string> types = new Dictionary<string, string>(); types.Add("Target", "Target.DisplayMessage"); types.Add("Plugin", "Plugin.InterceptMessage"); return types; } }
需要的接口:
- IPrinter,提供打印信息的接口
View Code
public interface IPrinter { void PrintMessage(Message message); }
- IPlugin,提供插件接口
View Code
public interface IPlugin { void Execute(Target.Message message); }
程序入口Main代码如下:
View Code
class Program { static void Main(string[] args) { //Initilize a instance of Message, and receive the content entered by the user. Target.Message message = new Target.Message() { Content = Console.ReadLine() }; new Processor(message); Console.Read(); } }
运行结果如下:
至此,完成了插件原理的模拟。