using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
namespace Autodesk.AutoCAD.Runtime
{
public abstract class ExtensionApplication : IExtensionApplication
{
void IExtensionApplication.Initialize()
{
try
{
this.Initialize();
}
catch( System.Exception ex )
{
Console.Beep();
WriteMessage( "\nAn error occured while loading {0}:\n\n{1}",
this.GetType().Assembly.Location,
ex.ToString()
);
throw ex;
}
}
static void WriteMessage( string fmt, params object[] args )
{
Document doc = ApplicationServices.Application.DocumentManager.MdiActiveDocument;
if( doc != null )
doc.Editor.WriteMessage( fmt, args );
}
// Derived types must override this to do initialization
// and do not need to worry about catching exceptions:
protected abstract void Initialize();
// Derived types can optionally override this to do finalization:
protected virtual void Terminate()
{
}
void IExtensionApplication.Terminate()
{
try
{
this.Terminate();
if( Terminating != null )
Terminating( this, EventArgs.Empty );
}
finally
{
Terminating = null;
if( disposables != null )
{
disposables.Dispose();
disposables = null;
}
}
}
// This event can be handled as an alternative way
// of doing termination handling:
public static event EventHandler Terminating = null;
static DisposableList
<IDisposable
> disposables
= new DisposableList
<IDisposable
>();
// Pass this method any IDisposable and it will be disposed before
// AutoCAD shuts down, when the Terminate() method is called.
public static void AddDisposable( IDisposable disposable )
{
if( disposables != null )
disposables.Add( disposable );
}
public static bool RemoveDisposable( IDisposable disposable )
{
if( disposables != null )
return disposables.Remove( disposable );
else
return false;
}
public static bool ContainsDisposable( IDisposable disposable )
{
if( disposables != null )
return disposables.Contains( disposable );
else
return false;
}
}
}
// DisposableList.cs
namespace System.Collections.Generic
{
public class DisposableList<T> : List<T>, IDisposable
where T : IDisposable
{
bool disposed = false;
/// <summary>
/// If true, contained items are disposed of in reverse order
/// (last to first).
///
/// Default value: false
/// </summary>
bool ReverseOrderedDispose
{
get;
set;
}
public DisposableList()
{
}
public DisposableList( int capacity )
: base( capacity )
{
}
public DisposableList( IEnumerable<T> collection )
: base( collection )
{
}
public DisposableList( System.Collections.IEnumerable collection )
: base( collection.Cast<T>() )
{
}
public void Dispose()
{
Dispose( true );
}
protected virtual void Dispose( bool disposing )
{
bool flag = this.disposed;
this.disposed = true;
if( disposing && !flag )
{
if( this.ReverseOrderedDispose )
base.Reverse();
using( IEnumerator<T> e = base.GetEnumerator() )
DisposeItems( e );
}
}
private void DisposeItems( IEnumerator<T> e )
{
while( e.MoveNext() )
{
try
{
T item = e.Current;
if( item != null )
item.Dispose();
}
catch
{
DisposeItems( e );
throw;
}
}
}
}
}
// Example use:
[assembly
: ExtensionApplication
( typeof( MyApplication
) )]
public class MyApplication : ExtensionApplication
{
protected override void Initialize()
{
// Do initialization here
// Create an object that implements IDisposable and
// let ExtensionApplication manage it:
ExtensionApplication.AddDisposable( myDisposable );
}
}