在Outlook中存在不同的域对象MailItem ,ContactItem,TaskItem,AppointmentItem,NoteItem...这些类都是继承ItemEvents_10_Event接口的。而且这些类里面都有EntryID,UserProperties,ItemProperties,Parent,Class,这些属性,都实现了Save(),Delete(),Display()方法。
如果想实现这个Adapter类的话,
第一,我可以获得这些公用的方法。
第二,我可以调用这些类公用的方法。
第三,我可以对这些类的事件做些扩展,比如在这些领域对象的事件上加一些取消的功能。
第一和第二两个从不明确的对象实例上面获得属性和运行方法,完全满足反射的要求。第三条只要把判断该对象是否满足ItemEvents_10_Event接口就可以了。所以该类的实现如下
public sealed class ItemAdapter
 {
  MSOutlook.ItemEvents_10_Event _outlookItem;
  Type _outlookItemType;

  public event CancelEventHandler Opening;
  public event CancelEventHandler Writing;
  public event CancelEventHandler Closing;
  public event CancelEventHandler Deleting;

  public static ItemAdapter FromObject(object obj)
  {
   if (obj is MSOutlook.ItemEvents_10_Event)              
    return new ItemAdapter((MSOutlook.ItemEvents_10_Event)obj);
   return null;
  }

  public ItemAdapter(MSOutlook.ItemEvents_10_Event item)
  {
   _outlookItem = item;
   _outlookItemType = _outlookItem.GetType();

   _outlookItem.Open += new MSOutlook.ItemEvents_10_OpenEventHandler(OnOpen);
            _outlookItem.Close += new MSOutlook.ItemEvents_10_CloseEventHandler(OnClose);
   _outlookItem.Write += new MSOutlook.ItemEvents_10_WriteEventHandler(OnWrite);
            _outlookItem.BeforeDelete += new MSOutlook.ItemEvents_10_BeforeDeleteEventHandler(OnDelete);
  }

  void OnClose(ref bool cancel)
  {
   CancelEventArgs args = new CancelEventArgs(cancel);
   Closing(this, args);
   cancel = args.Cancel;
  }

  void OnDelete(object Item, ref bool cancel)
  {
   CancelEventArgs args = new CancelEventArgs(cancel);
   Deleting(this, args);
   cancel = args.Cancel;
  }

  void OnWrite(ref bool cancel)
  {
   CancelEventArgs args = new CancelEventArgs(cancel);
   Writing(this, args);
   cancel = args.Cancel;
  }

  void OnOpen(ref bool cancel)
  {
   CancelEventArgs args = new CancelEventArgs(cancel);
   Opening(this, args);
   cancel = args.Cancel;
  }

  public MSOutlook.UserProperties UserProperties
  {
   get { return (MSOutlook.UserProperties)GetProperty("UserProperties"); }
  }

  public MSOutlook.ItemProperties ItemProperties
  {
   get { return (MSOutlook.ItemProperties)GetProperty("ItemProperties"); }
  }

  public string EntryID
  {
   get { return (string)GetProperty("EntryID"); }
  }

  public object Parent
  {
   get { return GetProperty("Parent"); }
  }

  public MSOutlook.OlObjectClass Class
  {
   get { return (MSOutlook.OlObjectClass)GetProperty("Class"); }
  }

  public void Save()
  {
   InvokeMethod("Save");
  }

  public void Delete()
  {
   InvokeMethod("Delete");
  }

  public void Display()
  {
   InvokeMethod("Display");
  }
  internal object GetProperty(string name)
  {
   return _outlookItemType.InvokeMember(
    name,
    BindingFlags.GetProperty,
    null, _outlookItem, null);
  }

  internal void SetProperty(string name, object value)
  {
   _outlookItemType.InvokeMember(
    name,
    BindingFlags.SetProperty,
    null, _outlookItem, new object[] { value });
  }

  internal object InvokeMethod(string name, params object[] parameters)
  {
   return _outlookItemType.InvokeMember(
    name,
    BindingFlags.InvokeMethod,
    null, _outlookItem, parameters);
  }

  public MSOutlook.AppointmentItem GetAsAppointment()
  {
   if (this.Class != MSOutlook.OlObjectClass.olAppointment)
    throw new ApplicationException(string.Format("Can't GetAsAppointment for {0}", this.Class));

   return (MSOutlook.AppointmentItem)_outlookItem;
  }

  public MSOutlook.TaskItem GetAsTask()
  {
   if (this.Class != MSOutlook.OlObjectClass.olTask)
    throw new ApplicationException(string.Format("Can't GetAsTask for {0}", this.Class));

   return (MSOutlook.TaskItem)_outlookItem;
  }

  public MSOutlook.PostItem GetAsPost()
  {
   if (this.Class != MSOutlook.OlObjectClass.olPost)
    throw new ApplicationException(string.Format("Can't GetAsPost for {0}", this.Class));

   return (MSOutlook.PostItem)_outlookItem;
  }

  public MSOutlook.MailItem GetAsMail()
  {
   if (this.Class != MSOutlook.OlObjectClass.olMail)
    throw new ApplicationException(string.Format("Can't GetAsMail for {0}", this.Class));

   return (MSOutlook.MailItem)_outlookItem;
  }
 }
其实第一第二并不满足Adapter模式的定义,第一第二只是一个具体的抽象,是对不同对象共同特征的一个封装,而第三条才满足Adapter模式的定义,所以该类实现的是两个功能。

posted on 2007-06-29 10:53  何东建  阅读(476)  评论(0编辑  收藏  举报