Made wrappers simpler by moving some functionality to ComWrapper. Does not currently build, backup commit before attempting to clean up ZPushFolder

This commit is contained in:
Patrick Simpson 2017-02-10 11:15:58 +01:00
parent 0eb4412ed4
commit b8b2edbfcc
14 changed files with 83 additions and 134 deletions

View File

@ -8,21 +8,12 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class AddressEntryWrapper : ComWrapper, IAddressEntry class AddressEntryWrapper : ComWrapper<NSOutlook.AddressEntry>, IAddressEntry
{ {
private NSOutlook.AddressEntry _item; internal AddressEntryWrapper(NSOutlook.AddressEntry item) : base(item)
internal AddressEntryWrapper(NSOutlook.AddressEntry item)
{ {
this._item = item;
} }
internal NSOutlook.AddressEntry RawItem { get { return _item; } } internal NSOutlook.AddressEntry RawItem { get { return _item; } }
protected override void DoRelease()
{
ComRelease.Release(_item);
_item = null;
}
} }
} }

View File

@ -25,20 +25,16 @@ using System.Threading.Tasks;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
public abstract class ComWrapper : IComWrapper abstract class RawComWrapper : IComWrapper
{ {
protected RawComWrapper()
/// <summary>
/// Creates a wrapper.
/// </summary>
internal ComWrapper()
{ {
Interlocked.Increment(ref Statistics.CreatedWrappers); Interlocked.Increment(ref Statistics.CreatedWrappers);
this._createdTrace = new System.Diagnostics.StackTrace(); this._createdTrace = new System.Diagnostics.StackTrace();
MustRelease = true; MustRelease = true;
} }
~ComWrapper() ~RawComWrapper()
{ {
Interlocked.Increment(ref Statistics.DeletedWrappers); Interlocked.Increment(ref Statistics.DeletedWrappers);
if (!_isDisposed) if (!_isDisposed)
@ -71,4 +67,27 @@ namespace Acacia.Stubs.OutlookWrappers
abstract protected void DoRelease(); abstract protected void DoRelease();
} }
abstract class ComWrapper<ItemType> : RawComWrapper
{
protected ItemType _item { get; private set; }
/// <summary>
/// Creates a wrapper.
/// </summary>
protected ComWrapper(ItemType item)
{
this._item = item;
}
override protected void DoRelease()
{
if (MustRelease)
{
ComRelease.Release(_item);
_item = default(ItemType);
}
}
}
} }

View File

@ -10,7 +10,7 @@ using stdole;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class CommandBarsWrapper : ComWrapper, ICommandBars class CommandBarsWrapper : ComWrapper<NSOffice.CommandBars>, ICommandBars
{ {
private class MSOCommand : IMSOCommand private class MSOCommand : IMSOCommand
{ {
@ -37,23 +37,13 @@ namespace Acacia.Stubs.OutlookWrappers
} }
} }
private NSOffice.CommandBars _item; public CommandBarsWrapper(NSOffice.CommandBars item) : base(item)
public CommandBarsWrapper(NSOffice.CommandBars item)
{ {
this._item = item;
} }
public IMSOCommand GetMso(string id) public IMSOCommand GetMso(string id)
{ {
return new MSOCommand(this, id); return new MSOCommand(this, id);
} }
// TODO: make TypedComWrapper
protected override void DoRelease()
{
ComRelease.Release(_item);
_item = null;
}
} }
} }

View File

@ -8,19 +8,10 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class ExplorerWrapper : ComWrapper, IExplorer class ExplorerWrapper : ComWrapper<NSOutlook.Explorer>, IExplorer
{ {
private NSOutlook.Explorer _item; public ExplorerWrapper(NSOutlook.Explorer item) : base(item)
public ExplorerWrapper(NSOutlook.Explorer item)
{ {
this._item = item;
}
protected override void DoRelease()
{
ComRelease.Release(_item);
_item = null;
} }
public ICommandBars GetCommandBars() public ICommandBars GetCommandBars()

View File

@ -26,7 +26,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
public class FolderWrapper : OutlookWrapper<NSOutlook.Folder>, IFolder class FolderWrapper : OutlookWrapper<NSOutlook.Folder>, IFolder
{ {
public FolderWrapper(NSOutlook.MAPIFolder folder) public FolderWrapper(NSOutlook.MAPIFolder folder)
: :
@ -124,22 +124,20 @@ namespace Acacia.Stubs.OutlookWrappers
#region Enumeration #region Enumeration
public class ItemsEnumerator<ItemType> : ComWrapper, IEnumerator<ItemType> public class ItemsEnumerator<ItemType> : ComWrapper<NSOutlook.Items>, IEnumerator<ItemType>
where ItemType : IItem where ItemType : IItem
{ {
private NSOutlook.Items _items;
private IEnumerator _enum; private IEnumerator _enum;
private ItemType _last; private ItemType _last;
public ItemsEnumerator(NSOutlook.Folder _folder, string field, bool descending) public ItemsEnumerator(NSOutlook.Folder folder, string field, bool descending) : base(folder.Items)
{ {
// TODO: can _items be released here already? // TODO: can _items be released here already?
this._items = _folder.Items;
if (field != null) if (field != null)
{ {
this._items.Sort("[" + field + "]", descending); this._item.Sort("[" + field + "]", descending);
} }
this._enum = _items.GetEnumerator(); this._enum = _item.GetEnumerator();
} }
protected override void DoRelease() protected override void DoRelease()
@ -152,11 +150,7 @@ namespace Acacia.Stubs.OutlookWrappers
ComRelease.Release(_enum); ComRelease.Release(_enum);
_enum = null; _enum = null;
} }
if (_items != null) base.DoRelease();
{
ComRelease.Release(_items);
_items = null;
}
} }
public ItemType Current public ItemType Current

View File

@ -8,7 +8,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
abstract public class OutlookItemWrapper<ItemType> : OutlookWrapper<ItemType> abstract class OutlookItemWrapper<ItemType> : OutlookWrapper<ItemType>
{ {
public OutlookItemWrapper(ItemType item) public OutlookItemWrapper(ItemType item)
: :

View File

@ -29,37 +29,28 @@ namespace Acacia.Stubs.OutlookWrappers
/// <summary> /// <summary>
/// Helper for Outlook wrapper implementations /// Helper for Outlook wrapper implementations
/// </summary> /// </summary>
abstract public class OutlookWrapper<ItemType> : ComWrapper abstract class OutlookWrapper<ItemType> : ComWrapper<ItemType>
{ {
#region Construction / Destruction #region Construction / Destruction
protected ItemType _item;
/// <summary> /// <summary>
/// Creates a wrapper. /// Creates a wrapper.
/// </summary> /// </summary>
internal OutlookWrapper(ItemType item) internal OutlookWrapper(ItemType item) : base(item)
{ {
this._item = item;
} }
protected override void DoRelease() protected override void DoRelease()
{ {
// Always release props, as we allocated that
if (_props != null) if (_props != null)
{ {
ComRelease.Release(_props); ComRelease.Release(_props);
_props = null; _props = null;
} }
if (MustRelease) base.DoRelease();
{
if (_item != null)
{
ComRelease.Release(_item);
_item = default(ItemType);
}
}
} }
#endregion #endregion

View File

@ -8,23 +8,14 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class RecipientWrapper : ComWrapper, IRecipient class RecipientWrapper : ComWrapper<NSOutlook.Recipient>, IRecipient
{ {
private NSOutlook.Recipient _item; internal RecipientWrapper(NSOutlook.Recipient item) : base(item)
internal RecipientWrapper(NSOutlook.Recipient item)
{ {
this._item = item;
} }
internal NSOutlook.Recipient RawItem { get { return _item; } } internal NSOutlook.Recipient RawItem { get { return _item; } }
protected override void DoRelease()
{
ComRelease.Release(_item);
_item = null;
}
public bool IsResolved public bool IsResolved
{ {
get get

View File

@ -24,7 +24,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class SearchWrapper<ItemType> : ComWrapper, ISearch<ItemType> class SearchWrapper<ItemType> : ComWrapper<NSOutlook.Items>, ISearch<ItemType>
where ItemType : IItem where ItemType : IItem
{ {
private interface SearchTerm private interface SearchTerm
@ -151,21 +151,13 @@ namespace Acacia.Stubs.OutlookWrappers
} }
private readonly List<SearchTerm> terms = new List<SearchTerm>(); private readonly List<SearchTerm> terms = new List<SearchTerm>();
private NSOutlook.Items _items;
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
/// <param name="items">The items to search. The new object takes ownership</param> /// <param name="items">The items to search. The new object takes ownership</param>
public SearchWrapper(NSOutlook.Items items) public SearchWrapper(NSOutlook.Items items) : base(items)
{ {
this._items = items;
}
protected override void DoRelease()
{
ComRelease.Release(_items);
_items = null;
} }
public ISearchOperator AddOperator(SearchOperator oper) public ISearchOperator AddOperator(SearchOperator oper)
@ -187,7 +179,7 @@ namespace Acacia.Stubs.OutlookWrappers
List<ItemType> values = new List<ItemType>(); List<ItemType> values = new List<ItemType>();
string filter = MakeFilter(); string filter = MakeFilter();
object value = _items.Find(filter); object value = _item.Find(filter);
while(value != null) while(value != null)
{ {
if (values.Count < maxResults) if (values.Count < maxResults)
@ -204,7 +196,7 @@ namespace Acacia.Stubs.OutlookWrappers
// Release if not returned. Keep looping to release any others // Release if not returned. Keep looping to release any others
ComRelease.Release(value); ComRelease.Release(value);
} }
value = _items.FindNext(); value = _item.FindNext();
} }
return values; return values;
} }
@ -212,7 +204,7 @@ namespace Acacia.Stubs.OutlookWrappers
public ItemType SearchOne() public ItemType SearchOne()
{ {
// Wrap manages com object in value // Wrap manages com object in value
object value = _items.Find(MakeFilter()); object value = _item.Find(MakeFilter());
if (value == null) if (value == null)
return default(ItemType); return default(ItemType);
return Mapping.Wrap<ItemType>(value); return Mapping.Wrap<ItemType>(value);

View File

@ -25,7 +25,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
public class StorageItemWrapper : OutlookItemWrapper<NSOutlook.StorageItem>, IStorageItem class StorageItemWrapper : OutlookItemWrapper<NSOutlook.StorageItem>, IStorageItem
{ {
public StorageItemWrapper(NSOutlook.StorageItem item) public StorageItemWrapper(NSOutlook.StorageItem item)
: :

View File

@ -24,37 +24,28 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers namespace Acacia.Stubs.OutlookWrappers
{ {
class StoreWrapper : ComWrapper, IStore class StoreWrapper : ComWrapper<NSOutlook.Store>, IStore
{ {
internal static IStore Wrap(NSOutlook.Store store) internal static IStore Wrap(NSOutlook.Store store)
{ {
return store == null ? null : new StoreWrapper(store); return store == null ? null : new StoreWrapper(store);
} }
private NSOutlook.Store _store; private StoreWrapper(NSOutlook.Store store) : base(store)
private StoreWrapper(NSOutlook.Store store)
{ {
this._store = store;
}
protected override void DoRelease()
{
ComRelease.Release(_store);
_store = null;
} }
public IFolder GetRootFolder() public IFolder GetRootFolder()
{ {
// FolderWrapper manages the returned Folder // FolderWrapper manages the returned Folder
return new FolderWrapper((NSOutlook.Folder)_store.GetRootFolder()); return new FolderWrapper((NSOutlook.Folder)_item.GetRootFolder());
} }
public IItem GetItemFromID(string id) public IItem GetItemFromID(string id)
{ {
using (ComRelease com = new ComRelease()) using (ComRelease com = new ComRelease())
{ {
NSOutlook.NameSpace nmspace = com.Add(_store.Session); NSOutlook.NameSpace nmspace = com.Add(_item.Session);
// Get the item; the wrapper manages it // Get the item; the wrapper manages it
object o = nmspace.GetItemFromID(id); object o = nmspace.GetItemFromID(id);
@ -62,17 +53,17 @@ namespace Acacia.Stubs.OutlookWrappers
} }
} }
public string DisplayName { get { return _store.DisplayName; } } public string DisplayName { get { return _item.DisplayName; } }
public string StoreID { get { return _store.StoreID; } } public string StoreID { get { return _item.StoreID; } }
public bool IsFileStore { get { return _store.IsDataFileStore; } } public bool IsFileStore { get { return _item.IsDataFileStore; } }
public string FilePath { get { return _store.FilePath; } } public string FilePath { get { return _item.FilePath; } }
public void EmptyDeletedItems() public void EmptyDeletedItems()
{ {
using (ComRelease com = new ComRelease()) using (ComRelease com = new ComRelease())
{ {
NSOutlook.MAPIFolder f = _store.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems); NSOutlook.MAPIFolder f = _item.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems);
if (f != null) if (f != null)
{ {
com.Add(f); com.Add(f);

View File

@ -223,17 +223,15 @@ namespace Acacia.Utils
} }
} }
private class MailEventHooker : ComWrapper private class MailEventHooker : ComWrapper<NSOutlook.ItemEvents_10_Event>
{ {
private NSOutlook.ItemEvents_10_Event _itemEvents;
private readonly MailEvents _events; private readonly MailEvents _events;
// TODO: remove id and debug logging // TODO: remove id and debug logging
private int _id; private int _id;
private static int nextId; private static int nextId;
public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) : base(itemEvents)
{ {
this._itemEvents = itemEvents;
this._id = ++nextId; this._id = ++nextId;
this._events = events; this._events = events;
HookEvents(true); HookEvents(true);
@ -250,23 +248,23 @@ namespace Acacia.Utils
{ {
if (add) if (add)
{ {
_itemEvents.BeforeDelete += HandleBeforeDelete; _item.BeforeDelete += HandleBeforeDelete;
_itemEvents.Forward += HandleForward; _item.Forward += HandleForward;
_itemEvents.Read += HandleRead; _item.Read += HandleRead;
_itemEvents.Reply += HandleReply; _item.Reply += HandleReply;
_itemEvents.ReplyAll += HandleReplyAll; _item.ReplyAll += HandleReplyAll;
_itemEvents.Unload += HandleUnload; _item.Unload += HandleUnload;
_itemEvents.Write += HandleWrite; _item.Write += HandleWrite;
} }
else else
{ {
_itemEvents.BeforeDelete -= HandleBeforeDelete; _item.BeforeDelete -= HandleBeforeDelete;
_itemEvents.Forward -= HandleForward; _item.Forward -= HandleForward;
_itemEvents.Read -= HandleRead; _item.Read -= HandleRead;
_itemEvents.Reply -= HandleReply; _item.Reply -= HandleReply;
_itemEvents.ReplyAll -= HandleReplyAll; _item.ReplyAll -= HandleReplyAll;
_itemEvents.Unload -= HandleUnload; _item.Unload -= HandleUnload;
_itemEvents.Write -= HandleWrite; _item.Write -= HandleWrite;
} }
} }
@ -279,25 +277,25 @@ namespace Acacia.Utils
private void HandleForward(object response, ref bool cancel) private void HandleForward(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleForward: {0}", _id); Logger.Instance.Debug(this, "HandleForward: {0}", _id);
_events.OnForward(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
} }
private void HandleRead() private void HandleRead()
{ {
Logger.Instance.Debug(this, "HandleRead: {0}", _id); Logger.Instance.Debug(this, "HandleRead: {0}", _id);
_events.OnRead(_itemEvents as NSOutlook.MailItem); _events.OnRead(_item as NSOutlook.MailItem);
} }
private void HandleReply(object response, ref bool cancel) private void HandleReply(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleReply: {0}", _id); Logger.Instance.Debug(this, "HandleReply: {0}", _id);
_events.OnReply(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
} }
private void HandleReplyAll(object response, ref bool cancel) private void HandleReplyAll(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id); Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
_events.OnReplyAll(_itemEvents as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
} }
private void HandleUnload() private void HandleUnload()
@ -311,7 +309,7 @@ namespace Acacia.Utils
private void HandleWrite(ref bool cancel) private void HandleWrite(ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleWrite: {0}", _id); Logger.Instance.Debug(this, "HandleWrite: {0}", _id);
_events.OnWrite(_itemEvents, ref cancel); _events.OnWrite(_item, ref cancel);
} }
} }

View File

@ -252,7 +252,7 @@ namespace Acacia.ZPush.Connect
} }
} }
private class Request : ComWrapper private class Request : RawComWrapper
{ {
private const string ACTIVESYNC_URL = "https://{0}/Microsoft-Server-ActiveSync?DeviceId={1}&Cmd={2}&User={3}&DeviceType={4}"; private const string ACTIVESYNC_URL = "https://{0}/Microsoft-Server-ActiveSync?DeviceId={1}&Cmd={2}&User={3}&DeviceType={4}";

View File

@ -26,6 +26,7 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush namespace Acacia.ZPush
{ {
// TODO: make this contain Folder instead of inheriting, then FolderWrapper needn't be public
public class ZPushFolder : FolderWrapper public class ZPushFolder : FolderWrapper
{ {
private readonly NSOutlook.Items _items; private readonly NSOutlook.Items _items;