lsdwyl 发表于 2015-9-13 13:40:20

对Outlook中的不同的实体类实现一个通用的Adapter类

  在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模式的定义,所以该类实现的是两个功能。
页: [1]
查看完整版本: 对Outlook中的不同的实体类实现一个通用的Adapter类