在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模式的定义,所以该类实现的是两个功能。