• 事件应用,为系统提供扩展功能


    在系统设计之初,有时可能需要给系统预留一下扩展接口,以便在系统开发的后期或者完成以后,方便给系统添加功能.BlogEngine.Net系统中扩展机制,其实就是事件的应用.
    扩展机制的本质:
    在实现持久化的类中,定义一个静态的事件成员,通过订阅事件来实现扩展功能.

    我根据BlogEngine.Net系统中用户发表评论后,系统发送邮件通知功能,来描述一下BlogEngine.Net的扩展机制.
    首先是扩展接口.也就是定义事件:
    public class Post
    {
        //.........
        public static event EventHandler<EventArgs> CommentAdded;
    }

    然后,定义一个负责引发事件的方法来通知已订阅事事件的对象,事件已经发生.
      protected virtual void OnCommentAdded(Comment comment)
      {
       if (CommentAdded != null)
       {
        CommentAdded(comment, new EventArgs());
       }
      }
    下面,就是在添加评论发表成功后,调用一下这个方法.
      public void AddComment(Comment comment)
      {
       CancelEventArgs e = new CancelEventArgs();
       OnAddingComment(comment, e);
       if (!e.Cancel)
       {
        Comments.Add(comment);
        DataUpdate();
        OnCommentAdded(comment);//这里
        SendNotifications(comment);
       }
      }

    到目前为止,仅仅是实现了一个自定义的事件.:-).这里有一个关键点,那就是事件成员,是静态的.
    下面再说一下,扩展功能的实现.

    [Extension("Sends an e-mail to the blog owner whenever a comment is added", "1.3", "BlogEngine.NET")]//这个Attribute的功能,是告诉扩展管理者,当前扩展的描述信息,版本信息以及作者.
    public class SendCommentMail
    {
     public SendCommentMail()
     {
      Post.CommentAdded += new EventHandler<EventArgs>(Post_CommentAdded);//订阅事件
     }

     private void Post_CommentAdded(object sender, EventArgs e)
     {
      //..具体的发邮件的代码.
     }
    }

    下面也是很关键的一点,就是将扩展的功能,应用到系统中.

      void Application_Start(object sender, EventArgs e)
      {
        try
        {
          // Mono does not use "__code" as the name of the App_Code assembly.
          // Rather, it uses "App_Code", which is case sensitive!
          string assemblyName = "__code";
          Type t = Type.GetType("Mono.Runtime");
          if (t != null)
            assemblyName = "App_Code";

          Assembly a = Assembly.Load(assemblyName);
          Type[] types = a.GetTypes();

          foreach (Type type in types)
          {
            object[] attributes = type.GetCustomAttributes(typeof(ExtensionAttribute), false);
            foreach (object attribute in attributes)
            {
              if (ExtensionManager.ExtensionEnabled(type.Name))
              {
                a.CreateInstance(type.FullName);
              }
            }
          }
        }
        catch (System.IO.FileNotFoundException)
        {
          // There are no extensions in the App_Code folder, this error can be safely ignored
        }
      }

    这种扩展还是比较好理解的,当然,它能做的事情,也可能比较少.:-)

    BlogEngine.Net是一个开源的Blog系统,地址:http://www.codeplex.com/blogengine
  • 相关阅读:
    [Swift]LeetCode239. 滑动窗口最大值 | Sliding Window Maximum
    [Swift]LeetCode238. 除自身以外数组的乘积 | Product of Array Except Self
    [Java]LeetCode237. 删除链表中的节点 | Delete Node in a Linked List
    [Swift]LeetCode236. 二叉树的最近公共祖先 | Lowest Common Ancestor of a Binary Tree
    [Swift]LeetCode235. 二叉搜索树的最近公共祖先 | Lowest Common Ancestor of a Binary Search Tree
    [Swift]LeetCode233. 数字1的个数 | Number of Digit One
    [Swift]LeetCode232. 用栈实现队列 | Implement Queue using Stacks
    [Swift]LeetCode230. 二叉搜索树中第K小的元素 | Kth Smallest Element in a BST
    [Swift]LeetCode229. 求众数 II | Majority Element II
    [Swift]LeetCode228. 汇总区间 | Summary Ranges
  • 原文地址:https://www.cnblogs.com/bqrm/p/1207156.html
Copyright © 2020-2023  润新知