Skip to content

Update Nice3point.Revit.Toolkit#63

Open
Nice3point wants to merge 1 commit intodevelopfrom
renovate/nice3point.revit.toolkit
Open

Update Nice3point.Revit.Toolkit#63
Nice3point wants to merge 1 commit intodevelopfrom
renovate/nice3point.revit.toolkit

Conversation

@Nice3point
Copy link
Copy Markdown
Owner

This PR contains the following updates:

Package Type Update Change
Nice3point.Revit.Toolkit nuget patch 2021.4.0-preview.4.202603102021.4.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2022.4.0-preview.4.202603102022.4.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2023.4.0-preview.4.202603102023.4.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2024.3.0-preview.4.202603102024.3.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2025.2.0-preview.4.202603102025.2.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2026.1.0-preview.4.202603102026.1.0-preview.5.20260329
Nice3point.Revit.Toolkit nuget patch 2027.0.0-preview.4.202603102027.0.0-preview.5.20260329

Warning

Some dependencies could not be looked up. Check the warning logs for more information.


Release Notes

Nice3point/RevitToolkit (Nice3point.Revit.Toolkit)

v2027.0.0-preview.5.20260329

Compare Source

External Events

New family of external event types replacing legacy ActionEventHandler, AsyncEventHandler:

  • ExternalEvent — synchronous external event that queues the handler via the Revit external event mechanism.
  • ExternalEvent<T> — generic synchronous external event that accepts an argument of type T.
  • AsyncExternalEvent — asynchronous external event with RaiseAsync() that returns a Task.
  • AsyncExternalEvent<T> — generic asynchronous external event with argument support.
  • AsyncRequestExternalEvent<TResult> — asynchronous external event that returns a result via RaiseAsync().
  • AsyncRequestExternalEvent<T, TResult> — generic asynchronous external event with argument and result support.
  • ExternalEventOptions — configuration flags for event behavior, including AllowDirectInvocation for direct execution in API context.

[!IMPORTANT]
Events do not need to be created inside the Revit API context — the Toolkit handles initialization automatically, so you can create them anywhere in your code and on any thread.

ExternalEvent Source Generator

New [ExternalEvent] attribute with incremental source generator that eliminates boilerplate for defining external events.
Annotate a method in a partial type and the generator produces typed event properties automatically:

public partial class MyViewModel : ObservableObject
{
    [ExternalEvent]
    private void DeleteWindows(UIApplication application)
    {
        var document = application.ActiveUIDocument.Document;
        using var transaction = new Transaction(document, "Delete windows");
        transaction.Start();
        document.Delete(document.GetInstanceIds(BuiltInCategory.OST_Windows));
        transaction.Commit();
    }
    
    [RelayCommand]
    private void DeleteWindows()
    {
        DeleteWindowsEvent.Raise();
    }
}

// Generates:
// public IExternalEvent DeleteWindowsEvent => field ??= new ExternalEvent(DeleteWindows);
// public IAsyncExternalEvent DeleteWindowsAsyncEvent => field ??= new AsyncExternalEvent(DeleteWindows);

Source generator supports multiple parameters, methods with extra parameters like private void DeleteWindows(string arg1, int arg2, bool arg3) also work.
Roslyn versions 4.14 and 5.0+ supported.

Roslyn Analyzers and Code Fixers

New analyzer package with diagnostics for [ExternalEvent] annotated methods:

  • RVTTK0001 — Method returns Task or Task<T>.
  • RVTTK0002 — Method is async void.
  • RVTTK0003 — Method is generic.
  • RVTTK0004 — Duplicate method overloads with [ExternalEvent].
  • RVTTK0005 — Containing type is not partial.
Context
  • 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 AsyncExternalApplication class for async/await support in external applications.
  • 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 overloads for BeginDialogSuppressionScope(): MessageBoxResult, TaskDialogResult, custom handler.

Improvements

  • Improve reflexion performance with UnsafeAccessor methods for .NET 8+.
  • Disposable scopes support nesting with reference counting.
  • Thread safety improvements with Lock class and Interlocked operations.
  • 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.UiApplication is obsolete, use Application instead.
  • ExternalCommand.UiDocument is obsolete, use Application.ActiveUIDocument instead.
  • ExternalCommand.Document is obsolete, use Application.ActiveUIDocument.Document instead.
  • ExternalApplication.UiApplication is obsolete, use RevitContext.UiApplication instead.
  • ActionEventHandler is now obsolete — use ExternalEvent or [ExternalEvent] source generator.
  • AsyncEventHandler is now obsolete — use AsyncExternalEvent or [ExternalEvent] source generator.
  • AsyncEventHandler<T> is now obsolete — use AsyncRequestExternalEvent<T> or [ExternalEvent] source generator.
  • IdlingEventHandler is now obsolete — use ExternalEvent or [ExternalEvent] source generator.

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(@&#8203;"C:\Libraries"))
{
    window.Show();
}

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

Replace legacy event handlers with new External Events:

// Before
private readonly ActionEventHandler _handler = new();

private void Execute()
{
    _handler.Raise(app =>
    {
        app.ActiveUIDocument.Document.Delete(elementId);
    });
}

// After
private readonly ExternalEvent _handler = new(app =>
{
    app.ActiveUIDocument.Document.Delete(elementId);
});

private void Execute()
{
    _handler.Raise();
}

Replace legacy async event handlers:

// Before
private readonly AsyncEventHandler _handler = new();

private async Task ExecuteAsync()
{
    await _handler.RaiseAsync(app =>
    {
        app.ActiveUIDocument.Document.Delete(elementId);
    });
}

// After
private readonly AsyncExternalEvent _handler = new(app =>
{
    app.ActiveUIDocument.Document.Delete(elementId);
});

private async Task ExecuteAsync()
{
    await _handler.RaiseAsync();
}

Or use the source generator to avoid boilerplate entirely:

// After (source generator)
partial class MyViewModel
{
    [ExternalEvent]
    private void DeleteElement(UIApplication application)
    {
        application.ActiveUIDocument.Document.Delete(elementId);
    }
}

// Usage:
DeleteElementEvent.Raise();
// or
await DeleteElementAsyncEvent.RaiseAsync();

Full changelog: Nice3point/RevitToolkit@2027.0.0-preview.4.20260310...2027.0.0-preview.5.20260329


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

@Nice3point Nice3point added the maintenance ⚙️ Some regular maintenance updates label Mar 30, 2026
Copilot AI review requested due to automatic review settings March 30, 2026 02:40
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates centrally-managed Revit Toolkit package versions across supported Revit versions (2021–2027) to the latest preview patch, keeping the solution’s Revit integration dependencies current.

Changes:

  • Bump Nice3point.Revit.Toolkit from *-preview.4.20260310 to *-preview.5.20260329 for Revit 2021–2027 via conditional central package versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance ⚙️ Some regular maintenance updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants