Skip to content

Releases: Nice3point/RevitToolkit

2027.0.0-preview.2.20260123

23 Jan 18:31

Choose a tag to compare

Pre-release

New Features

  • New RevitContext class for UI-level application context access
  • New RevitApiContext class for database-level application context access
  • New AsyncExternalCommand class for async/await support in external commands
  • New BeginDialogSuppressionScope() method with disposable pattern for dialog suppression
  • New BeginFailureSuppressionScope() method with disposable pattern for failure handling
  • New BeginAssemblyResolveScope() method with disposable pattern for dependency resolution
  • New BeginAssemblyResolveScope(string directory) overload for explicit path specification
  • New SetExceptionHandler() method for ActionEventHandler and IdlingEventHandler
  • New CancellationToken support for AsyncEventHandler and AsyncEventHandler<T>
  • New overloads for BeginDialogSuppressionScope(): MessageBoxResult, TaskDialogResult, custom handler

Improvements

  • Event handlers now use ConcurrentQueue for thread-safe action queuing
  • Disposable scopes support nesting with reference counting
  • Thread safety improvements with Lock class and Interlocked operations
  • UnsafeAccessor usage for .NET 8+ to improve performance
  • Removed SemaphoreSlim from AsyncEventHandler<T> for better performance
  • BeginAssemblyResolveScope now uses Stack to support nested scopes with different directories

Breaking Changes

  • Context class is now obsolete, use RevitContext or RevitApiContext instead
  • SuppressDialogs() / RestoreDialogs() are obsolete, use BeginDialogSuppressionScope() instead
  • SuppressFailures() / RestoreFailures() are obsolete, use BeginFailureSuppressionScope() instead
  • BeginAssemblyResolve() / EndAssemblyResolve() are obsolete, use BeginAssemblyResolveScope() instead
  • ExternalCommand.Document is obsolete, use ActiveDocument instead
  • ExternalCommand.UiDocument is obsolete, use ActiveUiDocument instead
  • ActionEventHandler.Cancel() method removed
  • IdlingEventHandler.Cancel() method removed

Automatic Migration with ReSharper/Rider

All obsolete methods are marked with [CodeTemplate] attributes, enabling automatic code conversion in JetBrains ReSharper and Rider. Simply place your cursor on the obsolete method and use the suggested quick-fix to update to the new API.

Migration Guide

Replace Context with RevitContext or RevitApiContext:

// Before
Context.ActiveDocument.Delete(elementId);
Context.Application.Username;

// After (auto-fix available)
RevitContext.ActiveDocument.Delete(elementId);
RevitApiContext.Application.Username;

Replace manual suppress/restore with disposable scopes:

// Before
try
{
    Context.SuppressDialogs();
    Context.SuppressFailures();
    // operations
}
finally
{
    Context.RestoreDialogs();
    Context.RestoreFailures();
}

// After (auto-fix available)
using (RevitContext.BeginDialogSuppressionScope())
using (RevitApiContext.BeginFailureSuppressionScope())
{
    // operations
}

Replace BeginAssemblyResolve/EndAssemblyResolve with scope:

// Before
try
{
    ResolveHelper.BeginAssemblyResolve<MyType>();
    window.Show();
}
finally
{
    ResolveHelper.EndAssemblyResolve();
}

// After (auto-fix available)
using (ResolveHelper.BeginAssemblyResolveScope<MyType>())
{
    window.Show();
}

New: Specify directory path directly for assembly resolution:

// Path-based (new)
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Libraries"))
{
    window.Show();
}

// Nested scopes (new) - searches innermost first
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Shared\Common"))
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Plugin"))
using (ResolveHelper.BeginAssemblyResolveScope<MyType>())
{
    // Searches: MyType directory -> Plugin -> Common
    window.Show();
}

Full changelog: 2027.0.0-preview.1.20260122...2027.0.0-preview.2.20260123

2027.0.0-preview.1.20260122

23 Jan 10:34

Choose a tag to compare

Pre-release

New Features

  • New RevitContext class for UI-level application context access
  • New RevitApiContext class for database-level application context access
  • New AsyncExternalCommand class for async/await support in external commands
  • New BeginDialogSuppressionScope() method with disposable pattern for dialog suppression
  • New BeginFailureSuppressionScope() method with disposable pattern for failure handling
  • New BeginAssemblyResolveScope() method with disposable pattern for dependency resolution
  • New BeginAssemblyResolveScope(string directory) overload for explicit path specification
  • New SetExceptionHandler() method for ActionEventHandler and IdlingEventHandler
  • New CancellationToken support for AsyncEventHandler and AsyncEventHandler<T>
  • New overloads for BeginDialogSuppressionScope(): MessageBoxResult, TaskDialogResult, custom handler

Improvements

  • Event handlers now use ConcurrentQueue for thread-safe action queuing
  • Disposable scopes support nesting with reference counting
  • Thread safety improvements with Lock class and Interlocked operations
  • UnsafeAccessor usage for .NET 8+ to improve performance
  • Removed SemaphoreSlim from AsyncEventHandler<T> for better performance
  • BeginAssemblyResolveScope now uses Stack to support nested scopes with different directories

Breaking Changes

  • Context class is now obsolete, use RevitContext or RevitApiContext instead
  • SuppressDialogs() / RestoreDialogs() are obsolete, use BeginDialogSuppressionScope() instead
  • SuppressFailures() / RestoreFailures() are obsolete, use BeginFailureSuppressionScope() instead
  • BeginAssemblyResolve() / EndAssemblyResolve() are obsolete, use BeginAssemblyResolveScope() instead
  • ExternalCommand.Document is obsolete, use ActiveDocument instead
  • ExternalCommand.UiDocument is obsolete, use ActiveUiDocument instead
  • ActionEventHandler.Cancel() method removed
  • IdlingEventHandler.Cancel() method removed

Automatic Migration with ReSharper/Rider

All obsolete methods are marked with [CodeTemplate] attributes, enabling automatic code conversion in JetBrains ReSharper and Rider. Simply place your cursor on the obsolete method and use the suggested quick-fix to update to the new API.

Migration Guide

Replace Context with RevitContext or RevitApiContext:

// Before
Context.ActiveDocument.Delete(elementId);
Context.Application.Username;

// After (auto-fix available)
RevitContext.ActiveDocument.Delete(elementId);
RevitApiContext.Application.Username;

Replace manual suppress/restore with disposable scopes:

// Before
try
{
    Context.SuppressDialogs();
    Context.SuppressFailures();
    // operations
}
finally
{
    Context.RestoreDialogs();
    Context.RestoreFailures();
}

// After (auto-fix available)
using (RevitContext.BeginDialogSuppressionScope())
using (RevitApiContext.BeginFailureSuppressionScope())
{
    // operations
}

Replace BeginAssemblyResolve/EndAssemblyResolve with scope:

// Before
try
{
    ResolveHelper.BeginAssemblyResolve<MyType>();
    window.Show();
}
finally
{
    ResolveHelper.EndAssemblyResolve();
}

// After (auto-fix available)
using (ResolveHelper.BeginAssemblyResolveScope<MyType>())
{
    window.Show();
}

New: Specify directory path directly for assembly resolution:

// Path-based (new)
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Libraries"))
{
    window.Show();
}

// Nested scopes (new) - searches innermost first
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Shared\Common"))
using (ResolveHelper.BeginAssemblyResolveScope(@"C:\Plugin"))
using (ResolveHelper.BeginAssemblyResolveScope<MyType>())
{
    // Searches: MyType directory -> Plugin -> Common
    window.Show();
}

Full changelog: 2026.0.0...2027.0.0-preview.1.20260122

2026.0.0

02 Apr 13:00

Choose a tag to compare

  • New Context.UiControlledApplication property. Helps to manipulate with the Revit ribbon, context menus outside ExternalApplication.
  • Now AsyncEventHandler{T} works in a multithreaded application and returns the result to each recipient.
  • Removed AssemblyLoadContext for addins isolation. It will be moved to Revit itself. More info.
  • Removed deprecated features.
  • Fixed dependency resolver to avoid conflict with the Revit runtime.

Full changelog: 2025.0.3...2026.0.0

2025.0.3

10 Oct 21:52

Choose a tag to compare

  • Removed JetBrains.Annotations dependency
  • Fixed typo in summary

Full changelog: 2025.0.2...2025.0.3

2025.0.2

01 Sep 10:38

Choose a tag to compare

  • Context global handlers:
    • SuppressFailures: suppresses the display of the Revit error and warning messages during transaction.
      By default, Revit uses manual error resolution control with user interaction.
      This method provides automatic resolution of all failures without notifying the user or interrupting the program
    • SuppressDialogs: suppresses the display of the Revit dialogs
  • Context global properties:
    • IsRevitInApiMode: determines whether Revit is in API mode or not.
    • Document is obsolete. Use ActiveDocument instead.
    • UiDocument is obsolete. Use ActiveUiDocument instead.
  • ExternalCommand.SuppressFailures is obsolete. Use Context class instead.
  • ExternalCommand.SuppressDialogs is obsolete. Use Context class instead.
  • ActionEventHandler now understands when it is in a Revit context and calls the handler immediately, without adding to the queue.
  • AsyncEventHandler now understands when it is in a Revit context and calls the handler immediately, without adding to the queue.
    Awaiting with await keyword will not cause a context switch, and you can still call API requests in the main Revit thread.
  • Nullable types support
  • Assembly load context internal optimizations
  • Readme updates, include extra samples

Full changelog: 2025.0.1...2025.0.2

2025.0.1

22 Jun 13:37

Choose a tag to compare

Add-in dependency isolation

This release introduces an isolated plugin dependency container using .NET AssemblyLoadContext.
This feature allows plugins to run in a separate, isolated context, ensuring independent execution and preventing conflicts from incompatible library versions.
This enhancement is available for Revit 2025 and higher, addressing the limitations of Revit's traditional plugin loading mechanism, which loads plugins by path without native support for isolation.

изображение

How It Works:

The core functionality centers on AssemblyLoadContext, which creates an isolated container for each plugin.
When a plugin is loaded, it is assigned a unique AssemblyLoadContext instance, encapsulating the plugin and its dependencies to prevent interference with other plugins or the main application.

To use this isolation feature, developers must inherit their classes from:

  • ExternalCommand
  • ExternalApplication
  • ExternalDbApplication
  • ExternalCommandAvailability

These classes contain the built-in isolation mechanism under the hood.
Plugins using interfaces such as IExternalCommand will not benefit from this isolation and will run in the default context.

Limitations:

  • The isolated plugin context feature is available starting with Revit 2025.
  • For older Revit versions, this library uses a ResolveHelper to help load dependencies from the plugin's folder, but does not protect against conflicts arising from incompatible packages.
  • Additionally, plugins that do not inherit from the specified classes will not be isolated and may experience compatibility issues if they rely on the default context.

Improvements

  • Added ExternalCommandAvailability class.

    Starting with Revit 2025, ExternalCommandAvailability uses AssemblyLoadContext to isolate dependencies.
    If your implementation does not include dependencies, use the IExternalCommandAvailability interface to reduce memory allocation

  • Added AvailableCommandController class.

    IExternalCommandAvailability implementation.
    Controller providing permanent accessibility for External Command invocation. This means that it will always be available for execution, even when no Document is open. Usage:

    panel.AddPushButton<StartupCommand>("Execute")
        .SetAvailabilityController<AvailableCommandController>()

Full changelog: 2025.0.0...2025.0.1

2025.0.0

02 Apr 11:16

Choose a tag to compare

  • Revit 2025 support
  • Add new DuplicateTypeNamesHandler overload
  • Optimize assembly resolve by @dosymep
  • Fix resolve raw assembly by @dosymep

Full changelog: 2024.0.1...2025.0.0

2024.0.1

02 Jan 22:17

Choose a tag to compare

  • New Context class.

    Provides computed properties to retrieve Revit objects in the current session. Values are provided even outside the Revit context.

    • Context.UiApplication;
    • Context.Application;
    • Context.UiDocument;
    • Context.Document;
    • Context.ActiveView;
    • Context.ActiveGraphicalView;
    • Context.ActiveView;
    Context.Document.Create.NewFamilyInstance();
    Context.ActiveView = view;
  • New FrameworkElementCreator. Creates FrameworkElements for the dock pane.

    DockablePaneProvider.Register(application)
        .SetId(guid)
        .SetTitle(title)
        .SetConfiguration(data =>
        {
            data.FrameworkElementCreator = new FrameworkElementCreator<DockPaneView>();
        });

    Available overloading with IServiceProvider, in case you use hosting.

  • ResolveHelper reworked. Now you need to specify a type to resolve dependencies. The directory where the type is defined will be used to search for dependencies.

    Enabled by default for all ExternalCommand and ExternalApplication, so only needed for direct invocation in special cases.

    The current version now disables all resolvers used in the domain to avoid conflicts, and to bypass cases where Revit loaded assemblies from another plugin's folder.

    try
    {
        ResolveHelper.BeginAssemblyResolve<DockView>();
        window.Show();
    }
    finally
    {
        ResolveHelper.EndAssemblyResolve();
    }

Full changelog: 2024.0.0...2024.0.1

2024.0.0

04 Apr 08:45

Choose a tag to compare

  • Revit 2024 support
  • New SaveSharedCoordinatesCallback
  • New ExternalDbApplication

ExternalCommand:

  • New SuppressFailures method

2023.0.12

28 Dec 16:22

Choose a tag to compare

New runtime attributes: init, required keywords support