// Copyright (c) 2012 Tony Tanzillo
using System;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using Autodesk.AutoCAD.ApplicationServices;
namespace namespace1
{
// Provides version-independent APIs that
// can run on AutoCAD R18 and R19.
// Note that in order to achieve version-independence
// No types or namespaces that are unique to AutoCAD
// 2013 can be used directly from this code or the
// assembly containing it.
// For that reason, this code should live in separate
// assemblies (one for each targeted release) and be
// referenced and used from other application code.
public static class VersionInteropHelper
{
// Document.GetAcadDocumentEx() Extension Method
//
// Returns the AcadDocument for the given Document.
//
// This extension method provides a version-independent
// way to obtain the AcadDocument object. Hence, it can
// be compiled against and run on any version of AutoCAD
// that uses .NET 3.5 or later (which is required for
// System.Linq.Expression)
//
// Usage:
//
// Include this code in your project and use GetAcadDocumentEx()
// exclusively, in lieu of using Document.AcadDocument on AutoCAD
// 2012 and earlier, and DocumentExtension.GetAcadDocument() on
// AutoCAD 2013 or later.
//
// This code also serves as an example of a general pattern
// that can be applied to abstract out other breaking changes
// in source code between AutoCAD 2012 and AutoCAD 2013.
public static object GetAcadDocumentEx( this Document doc )
{
if( getAcadDocumentMethod == null )
getAcadDocumentMethod = CreateGetAcadDocumentMethod();
return getAcadDocumentMethod( doc );
}
static Func<Document, object> getAcadDocumentMethod = null;
static Func<Document, object> CreateGetAcadDocumentMethod()
{
Expression<Func<Document, object>> result = null;
var parameters
= new ParameterExpression
[] { Expression
.Parameter( typeof( Document
),
"document") };
if( AcadVersion.Major > 18 )
{
// AcMgd.dll:
Type type
= typeof( Autodesk
.AutoCAD.Windows.PaletteSet ) .Assembly.GetType( "Autodesk.AutoCAD.ApplicationServices.DocumentExtension", true );
MethodInfo mi = type.GetMethod( "GetAcadDocument",
BindingFlags.Public | BindingFlags.Static
);
result = Expression.Lambda<Func<Document, object>>(
Expression.Call( mi, parameters ),
parameters
);
}
else
{
MethodInfo method
= typeof(Document
).GetProperty("AcadDocument").GetGetMethod(); result = Expression.Lambda<Func<Document, object>>(
Expression.Call( parameters[0], method ),
parameters[0]
);
}
return result.Compile();
}
// Let's all give a big round of applause to Autodesk for
// removing the Version property from the Application object
// in AcMgd.dll. In order for version-independent code to
// branch to different execution paths depending on whether
// it is running on R18 or R19, it must check the version of
// the application that it's running on at runtime.
//
// But, because they did not leave the version property on the
// Application object in AcMgd.dll, there is no direct version-
// independent way to get the application version... LMAO
// A version-independent way to get the AutoCAD version at runtime (LOL)
public static Version AcadVersion
{
get
{
return typeof( Document
).Assembly.GetName().Version; }
}
}
}