Skip to content

Commit 239af2f

Browse files
committed
Remove AssemblyLoadContext
1 parent 813bd00 commit 239af2f

File tree

7 files changed

+6
-296
lines changed

7 files changed

+6
-296
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Release 2025.0.4-preview.1.0
2+
3+
- New `Context.UiControlledApplication` property. Helps to manipulate with the Revit ribbon, context menus outside ExternalApplication.
4+
15
# Release 2025.0.3
26

37
- Removed JetBrains.Annotations dependency

Readme.md

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ Package included by default in [Revit Templates](https://github.com/Nice3point/R
4949
* [DockablePaneProvider](#dockablepaneprovider)
5050
* [Helpers](#helpers)
5151
* [ResolveHelper](#resolvehelper)
52-
* [Add-ins Dependency Isolation](#add-ins-dependency-isolation)
5352
* [Samples](#samples)
5453
* [External application flow control](#external-application-flow-control)
5554
* [External command flow control](#external-command-flow-control)
@@ -81,8 +80,6 @@ public class Command : ExternalCommand
8180
**ExternalCommand** contains the logic for resolving dependencies.
8281
Now you may not encounter a `FileNotFoundException`. Dependencies are searched in the plugin folder.
8382

84-
Starting with Revit 2025, **ExternalCommand** is executed in an isolated context, providing independent execution and preventing conflicts due to incompatible library versions.
85-
8683
### ExternalApplication
8784

8885
Contains an implementation for **IExternalApplication**.
@@ -113,8 +110,6 @@ public class Application : ExternalApplication
113110
**ExternalApplication** contains the logic for resolving dependencies.
114111
Now you may not encounter a `FileNotFoundException`. Dependencies are searched in the plugin folder.
115112

116-
Starting with Revit 2025, **ExternalApplication** is executed in an isolated context, providing independent execution and preventing conflicts due to incompatible library versions.
117-
118113
### ExternalDBApplication
119114

120115
Contains an implementation for **IExternalDBApplication**.
@@ -139,9 +134,6 @@ Override method **OnShutdown()** to execute some tasks when Revit shuts down. Yo
139134
**ExternalDBApplication** contains the logic for resolving dependencies.
140135
Now you may not encounter a `FileNotFoundException`. Dependencies are searched in the plugin folder.
141136

142-
Starting with Revit 2025, **ExternalDBApplication** is executed in an isolated context, providing independent execution and preventing conflicts due to incompatible library
143-
versions.
144-
145137
### External events
146138

147139
Contains an implementations for **IExternalEventHandler**.
@@ -529,7 +521,7 @@ Provides auxiliary components
529521

530522
#### ResolveHelper
531523

532-
Provides handlers to resolve dependencies for Revit 2024 and older.
524+
Provides handlers to resolve dependencies for Revit 2025 and older.
533525

534526
```c#
535527
try
@@ -545,37 +537,6 @@ finally
545537

546538
Enabled by default for `ExternalCommand`, `ExternalApplication` and `ExternalDBApplication`.
547539

548-
#### Add-ins Dependency Isolation
549-
550-
Provides dependency isolation for Revit 2025 and earlier.
551-
552-
This library enables running plugins in an isolated context using
553-
.NET [AssemblyLoadContext](https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext).
554-
Each plugin executes independently, preventing conflicts from incompatible library versions.
555-
556-
How It Works:
557-
558-
The core functionality centers on `AssemblyLoadContext`, which creates an isolated container for each plugin.
559-
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
560-
main application.
561-
562-
To use this isolation feature, developers must inherit their classes from:
563-
564-
- ExternalCommand
565-
- ExternalApplication
566-
- ExternalDbApplication
567-
- ExternalCommandAvailability
568-
569-
These classes contain the built-in isolation mechanism under the hood.
570-
Plugins using interfaces such as `IExternalCommand` will not benefit from this isolation and will run in the default context.
571-
572-
Limitations:
573-
574-
- The isolated context feature is available starting with Revit 2025.
575-
- 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
576-
packages.
577-
- 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.
578-
579540
### Samples
580541

581542
#### External application flow control

source/Nice3point.Revit.Toolkit/External/ExternalApplication.cs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ namespace Nice3point.Revit.Toolkit.External;
1313
[PublicAPI]
1414
public abstract class ExternalApplication : IExternalApplication
1515
{
16-
#if NETCOREAPP
17-
private object? _isolatedInstance;
18-
#endif
19-
2016
/// <summary>
2117
/// Indicates if the external application completes its work successfully.
2218
/// </summary>
@@ -40,21 +36,9 @@ public abstract class ExternalApplication : IExternalApplication
4036
public Result OnStartup(UIControlledApplication application)
4137
{
4238
var currentType = GetType();
43-
44-
#if NETCOREAPP
45-
if (!AddinLoadContext.CheckAccess(currentType))
46-
{
47-
var dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
48-
_isolatedInstance = dependenciesProvider.CreateInstance(currentType);
49-
return AddinLoadContext.Invoke(_isolatedInstance, nameof(OnStartup), application);
50-
}
51-
#endif
52-
39+
5340
Application = application;
5441

55-
#if NETCOREAPP
56-
OnStartup();
57-
#else
5842
try
5943
{
6044
ResolveHelper.BeginAssemblyResolve(currentType);
@@ -64,7 +48,6 @@ public Result OnStartup(UIControlledApplication application)
6448
{
6549
ResolveHelper.EndAssemblyResolve();
6650
}
67-
#endif
6851

6952
return Result;
7053
}
@@ -75,14 +58,6 @@ public Result OnShutdown(UIControlledApplication application)
7558
{
7659
var currentType = GetType();
7760

78-
#if NETCOREAPP
79-
if (!AddinLoadContext.CheckAccess(currentType))
80-
{
81-
return AddinLoadContext.Invoke(_isolatedInstance!, nameof(OnShutdown), application);
82-
}
83-
84-
OnShutdown();
85-
#else
8661
try
8762
{
8863
ResolveHelper.BeginAssemblyResolve(currentType);
@@ -92,7 +67,6 @@ public Result OnShutdown(UIControlledApplication application)
9267
{
9368
ResolveHelper.EndAssemblyResolve();
9469
}
95-
#endif
9670

9771
return Result.Succeeded;
9872
}

source/Nice3point.Revit.Toolkit/External/ExternalCommand.cs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,13 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme
7373
{
7474
var currentType = GetType();
7575

76-
#if NETCOREAPP
77-
if (!AddinLoadContext.CheckAccess(currentType))
78-
{
79-
var dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
80-
var instance = dependenciesProvider.CreateInstance(currentType);
81-
return AddinLoadContext.Invoke(instance, commandData, ref message, elements);
82-
}
83-
#endif
84-
8576
ElementSet = elements;
8677
ErrorMessage = message;
8778
ExternalCommandData = commandData;
8879

8980
try
9081
{
91-
#if !NETCOREAPP
9282
ResolveHelper.BeginAssemblyResolve(currentType);
93-
#endif
9483
Execute();
9584
}
9685
catch
@@ -107,9 +96,7 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme
10796
finally
10897
{
10998
message = ErrorMessage;
110-
#if !NETCOREAPP
11199
ResolveHelper.EndAssemblyResolve();
112-
#endif
113100
Context.RestoreFailures();
114101
Context.RestoreDialogs();
115102
}

source/Nice3point.Revit.Toolkit/External/ExternalCommandAvailability.cs

Lines changed: 0 additions & 54 deletions
This file was deleted.

source/Nice3point.Revit.Toolkit/External/ExternalDBApplication.cs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,8 @@ public ExternalDBApplicationResult OnStartup(ControlledApplication application)
3636
{
3737
var currentType = GetType();
3838

39-
#if NETCOREAPP
40-
if (!AddinLoadContext.CheckAccess(currentType))
41-
{
42-
var dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
43-
_isolatedInstance = dependenciesProvider.CreateInstance(currentType);
44-
return AddinLoadContext.Invoke(_isolatedInstance, nameof(OnStartup), application);
45-
}
46-
#endif
47-
4839
Application = application;
4940

50-
#if NETCOREAPP
51-
OnStartup();
52-
#else
5341
try
5442
{
5543
ResolveHelper.BeginAssemblyResolve(currentType);
@@ -59,7 +47,6 @@ public ExternalDBApplicationResult OnStartup(ControlledApplication application)
5947
{
6048
ResolveHelper.EndAssemblyResolve();
6149
}
62-
#endif
6350

6451
return Result;
6552
}
@@ -70,14 +57,6 @@ public ExternalDBApplicationResult OnShutdown(ControlledApplication application)
7057
{
7158
var currentType = GetType();
7259

73-
#if NETCOREAPP
74-
if (!AddinLoadContext.CheckAccess(currentType))
75-
{
76-
return AddinLoadContext.Invoke(_isolatedInstance!, nameof(OnShutdown), application);
77-
}
78-
79-
OnShutdown();
80-
#else
8160
try
8261
{
8362
ResolveHelper.BeginAssemblyResolve(currentType);
@@ -87,7 +66,6 @@ public ExternalDBApplicationResult OnShutdown(ControlledApplication application)
8766
{
8867
ResolveHelper.EndAssemblyResolve();
8968
}
90-
#endif
9169

9270
return ExternalDBApplicationResult.Succeeded;
9371
}

0 commit comments

Comments
 (0)