Skip to content

D4 r da 2027#3384

Draft
pinzart90 wants to merge 78 commits into
Revit2027from
D4R_DA_2027
Draft

D4 r da 2027#3384
pinzart90 wants to merge 78 commits into
Revit2027from
D4R_DA_2027

Conversation

@pinzart90
Copy link
Copy Markdown
Collaborator

Please Note:

  1. Before submitting the PR, please review How to Contribute to Dynamo
  2. Dynamo Team will meet 1x a month to review PRs found on Github (Issues will be handled separately)
  3. PRs will be reviewed from oldest to newest
  4. If a reviewed PR requires changes by the owner, the owner of the PR has 30 days to respond. If the PR has seen no activity by the next session, it will be either closed by the team or depending on its utility will be taken over by someone on the team
  5. PRs should use either Dynamo's default PR template or one of these other template options in order to be considered for review.
  6. PRs that do not have one of the Dynamo PR templates completely filled out with all declarations satisfied will not be reviewed by the Dynamo team.
  7. PRs made to the DynamoRevit repo will need to be cherry-picked into all the DynamoRevit Release branches that Dynamo supports. Contributors will be responsible for cherry-picking their reviewed commits to the other branches after a LGTM label is added to the PR.

Purpose

(FILL ME IN) This section describes why this PR is here. Usually it would include a reference
to the tracking task that it is part or all of the solution for.

Declarations

Check these if you believe they are true

  • The code base is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • Snapshot of UI changes, if any.

Reviewers

(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of

zeusongit and others added 30 commits January 12, 2024 15:15
OnRequestsCrashPrompt function
Update Greg to 3.0.1
Update Greg to 3.0.1
* update GregRevitAuth to 3.0.8935.26399
* update GregRevitAuth to 3.0.8935.26399
* add OOTB templates
* update Dynamo Core build to 3.2.1.5366
* add wrapper over Revit RoofBase class to D4R Roof class

* cast value data type to parameter value data type in order to avoid blind pointer cast in revit later on

* cast value data type to parameter value data type, get parameter value data type from Storage type where value is null
pinzart90 and others added 21 commits May 13, 2025 13:03
What changed:
Ability to load Revit Cloud Models
("type":"versions:autodesk.bim360:C4RModel")

Documentation 

https://aps.autodesk.com/blog/new-sample-support-access-revit-cloud-model-revit-design-automation-engine

Not implemented yet: Cloud Shared models.
Does not work for regular rvt files stored on ACC (only supported in
Autocad for now) -
https://aps.autodesk.com/en/docs/design-automation/v3/developers_guide/reference-downloading/

TODO:
To access cloud models using Automation, you need to provide the user
context through a special workitem argument; adsk3LeggedToken,
scope=code:all needs to be added to your authorization call.
I need to add an example in the scripts/postman collections
version of #3296 for 2027
Please Note:
1. Before submitting the PR, please review [How to Contribute to
Dynamo](https://github.com/DynamoDS/Dynamo/blob/master/CONTRIBUTING.md)
2. Dynamo Team will meet 1x a month to review PRs found on Github
(Issues will be handled separately)
3. PRs will be reviewed from oldest to newest
4. If a reviewed PR requires changes by the owner, the owner of the PR
has 30 days to respond. If the PR has seen no activity by the next
session, it will be either closed by the team or depending on its
utility will be taken over by someone on the team
5. PRs should use either Dynamo's default PR template or [one of these
other template
options](https://github.com/DynamoDS/Dynamo/wiki/Choosing-a-Pull-Request-Template)
in order to be considered for review.
6. PRs that do not have one of the Dynamo PR templates completely filled
out with all declarations satisfied will not be reviewed by the Dynamo
team.
7. PRs made to the `DynamoRevit` repo will need to be cherry-picked into
all the DynamoRevit Release branches that Dynamo supports. Contributors
will be responsible for cherry-picking their reviewed commits to the
other branches after a `LGTM` label is added to the PR.

(FILL ME IN) This section describes why this PR is here. Usually it
would include a reference
to the tracking task that it is part or all of the solution for.

Check these if you believe they are true

- [ ] The code base is in a better state after this PR
- [ ] Is documented according to the
[standards](https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards)
- [ ] The level of testing this PR includes is appropriate
- [ ] User facing strings, if any, are extracted into `*.resx` files
- [ ] Snapshot of UI changes, if any.

(FILL ME IN) Reviewer 1  (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

(FILL ME IN, Optional) Names of anyone else you wish to be notified of
Add default output folder

Check these if you believe they are true

- [ ] The code base is in a better state after this PR
- [ ] Is documented according to the
[standards](https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards)
- [ ] The level of testing this PR includes is appropriate
- [ ] User facing strings, if any, are extracted into `*.resx` files
- [ ] Snapshot of UI changes, if any.

(FILL ME IN) Reviewer 1  (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

(FILL ME IN, Optional) Names of anyone else you wish to be notified of
Bogdan: When I run a graph that modifies the rvt it looks like we don't
get back the modified version ? Is this expected ?

(FILL ME IN) This section describes why this PR is here. Usually it
would include a reference
to the tracking task that it is part or all of the solution for.

Check these if you believe they are true

- [ ] The code base is in a better state after this PR
- [ ] Is documented according to the
[standards](https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards)
- [ ] The level of testing this PR includes is appropriate
- [ ] User facing strings, if any, are extracted into `*.resx` files
- [ ] Snapshot of UI changes, if any.

(FILL ME IN) Reviewer 1  (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

(FILL ME IN, Optional) Names of anyone else you wish to be notified of
@mjkkirschner
Copy link
Copy Markdown
Member

@pinzart90 are you looking for a review on this or just getting it spun up?

Copy link
Copy Markdown
Contributor

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

This PR introduces Design Automation (DA) support for DynamoRevit (targeting Revit 2027 / .NET 10), refactors ASM/libG preloading + assembly resolving into shared utilities, and updates Revit services/nodes/UI to compile/run under a headless DA build profile (DESIGN_AUTOMATION).

Changes:

  • Added DADynamoApp (DA entrypoint, logging/profiling, graph-run routing) and a dedicated DynamoRevit.DA.sln.
  • Introduced DA compile-time slicing (DESIGN_AUTOMATION) and updated RevitServices/RevitNodes/RevitNodesUI to avoid Revit UI APIs in DA builds.
  • Refactored ASM preload and internal node loading utilities, and centralized assembly resolution logic.

Reviewed changes

Copilot reviewed 46 out of 46 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
test/Libraries/RevitTestServices/RevitSystemTestBase.cs Switches ASM/libG preload + geometry factory path resolution to ASMPrealoaderUtils.
test/Libraries/RevitTestServices/RevitNodeTestBase.cs Uses ASMPrealoaderUtils.PreloadAsmFromRevit for test session setup.
test/Libraries/RevitServicesTests/RevitServicesTests.csproj Removes config-specific MSBuild property groups.
test/Libraries/RevitNodesTests/Elements/DirectShapeTests.cs Updates mesh creation helper calls to Mesh.ByPointsFaceIndices.
test/Libraries/RevitIntegrationTests/RevitSystemTests.csproj Adds DADynamoApp project reference for integration testing.
test/Libraries/RevitIntegrationTests/DALoggerTests.cs Adds DA logger/profiling integration test coverage (currently hits access issues).
src/Libraries/RevitServices/RevitServices.csproj Removes config-specific MSBuild groups; excludes threading code for _DA builds.
src/Libraries/RevitServices/Properties/AssemblyInfo.cs Expands InternalsVisibleTo to enable DA and other assemblies to access internals.
src/Libraries/RevitServices/Persistence/DocumentManager.cs Adds DA-friendly CurrentDBDocument handling and PrepareForDesignAutomation.
src/Libraries/RevitServices/Events/EventHandlerProxy.cs Adds singleton instance + DA compilation guards for UI view events.
src/Libraries/RevitNodesUI/SunPath.cs Switches to RevitServices event proxy and avoids UI events in DA builds.
src/Libraries/RevitNodesUI/SiteLocation.cs Moves node view customization behind DA guard; switches to RevitServices event proxy.
src/Libraries/RevitNodesUI/Selection.cs Switches document-open handling to RevitServices event proxy.
src/Libraries/RevitNodesUI/RevitTypes.cs Cleans up unused usings at file top.
src/Libraries/RevitNodesUI/RevitNodesUI.csproj Adds _DA build exclusions for UI controls/pages; restructures project file (now has duplicate refs).
src/Libraries/RevitNodesUI/RevitDropDown.cs Switches document-open handling to RevitServices event proxy.
src/Libraries/RevitNodesUI/Elements.cs Guards view-activated subscription for DA; switches to RevitServices event proxy.
src/Libraries/RevitNodes/Transaction/Transaction.cs Avoids UIDocument.RefreshActiveView() for DA builds.
src/Libraries/RevitNodes/RevitNodes.csproj Removes config-specific MSBuild property groups.
src/Libraries/RevitNodes/Properties/AssemblyInfo.cs Adds InternalsVisibleTo("DADynamoApp").
src/Libraries/RevitNodes/Elements/Views/View.cs Guards UI view-close logic for DA builds.
src/Libraries/RevitNodes/Elements/Views/StructuralPlanView.cs Uses CurrentDBDocument.Application instead of UI application for structure check.
src/Libraries/RevitNodes/Elements/Views/Sheet.cs Guards UI view-close logic for DA builds.
src/Libraries/RevitNodes/Elements/LinkElement.cs Guards UI-only zoom helper for DA builds; minor formatting cleanup.
src/Libraries/RevitNodes/Elements/Element.cs Guards UI-only view-close logic; uses DB ActiveView for overrides in DA context.
src/Libraries/RevitNodes/Elements/AdaptiveComponent.cs Uses CurrentDBDocument.Application.Create instead of UI application.
src/Libraries/Migrations/Migrations.csproj Removes config-specific MSBuild property groups.
src/DynamoRevitIcons/DynamoRevitIcons.csproj Removes config-specific MSBuild property groups.
src/DynamoRevit/Utilities/internal class DynamoRevitAssemblyResolver.cs New centralized assembly resolver (file path/name is problematic).
src/DynamoRevit/Utilities/DynamoRevitInternalNodes.cs Extracts internal package discovery/parsing from DynamoRevit.cs.
src/DynamoRevit/Utilities/ASMPreloader.cs Extracts ASM/libG preload + geometry factory path reflection helpers.
src/DynamoRevit/Properties/AssemblyInfo.cs Adds InternalsVisibleTo("DADynamoApp").
src/DynamoRevit/Models/RevitDynamoModel.cs Adds DA compilation guards; switches some active-view checks to DB document; switches to RevitServices proxy singleton.
src/DynamoRevit/DynamoRevitApp.cs Refactors event proxy usage and assembly resolving (currently introduces compile issues).
src/DynamoRevit/DynamoRevit.csproj Adds explicit core assembly references; adds _DA-specific compile removals; adjusts copy paths.
src/DynamoRevit/DynamoRevit.cs Uses extracted ASM preloader + internal nodes helpers; fixes RevitPathResolver argument usage.
src/DynamoRevit.DA.sln Adds a dedicated solution for DA build profile.
src/DynamoRevit.All.sln Adds additional project dependency entry.
src/DADynamoApp/SetupDARequest.cs Adds DA setup request model types (local/cloud inputs and save options).
src/DADynamoApp/DARunGraphController.cs Adds DA-specific controller wrapper for graph execution routing.
src/DADynamoApp/DALogger.cs Adds stdout-based logger with node output serialization/profiling support.
src/DADynamoApp/DAEntrypoint.cs Adds the DA external app entrypoint: model setup, handler wiring, python deps preinstall, run execution, save behavior.
src/DADynamoApp/DADynamoApp.csproj New DA app project definition and dependencies.
src/Config/CS_SDK.props Adds NET10_DA platform/TFM and DESIGN_AUTOMATION constant for _DA builds; adjusts project reference metadata.
src/BUILDSYSTEM_TODO.md Documents open build-system questions and known issues for net10/DA builds.
src/AssemblySharedInfoGenerator/AssemblyInfoGenerator.csproj Adjusts DebugSymbols/OutputPath settings (now duplicated).
Comments suppressed due to low confidence (1)

src/Libraries/RevitNodesUI/RevitNodesUI.csproj:67

  • RevitNodesUI.csproj includes the same three ProjectReferences twice (once without metadata, then again with <Private>False</Private>). This redundancy can lead to confusing MSBuild item state and makes it unclear which metadata is intended. Keep a single ItemGroup for these references and apply the desired metadata there.

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

public static EventHandlerProxy EventHandlerProxy
{
get { return proxy; }
get { return EventHandlerProxy.Instance; }
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

DynamoRevitApp defines a static property named EventHandlerProxy, and the getter currently references EventHandlerProxy.Instance, which resolves to the property name (not the RevitServices.EventHandler.EventHandlerProxy type) and will not compile. Use the fully-qualified type name in the getter (or rename the property) so the reference is unambiguous.

Suggested change
get { return EventHandlerProxy.Instance; }
get { return RevitServices.EventHandler.EventHandlerProxy.Instance; }

Copilot uses AI. Check for mistakes.
Comment on lines +303 to 307
ControlledApplication.DocumentClosed -= EventHandlerProxy.Instance.OnApplicationDocumentClosed;
ControlledApplication.DocumentOpened -= EventHandlerProxy.Instance.OnApplicationDocumentOpened;

proxy = null;
EventHandlerProxy.Instance = null;
}
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

EventHandlerProxy.Instance = null; will not compile (and even if it did, clearing a singleton instance like this is unsafe for any other subscribers that still hold references). Instead, keep the singleton instance alive and only unsubscribe the individual Revit application events (or add an explicit Dispose/ClearSubscribers method on the proxy if you truly need to drop handlers).

Copilot uses AI. Check for mistakes.
Comment thread src/DADynamoApp/DAEntrypoint.cs Outdated
Comment on lines +63 to +67
private static void CurrentDomain_ProcessExit(object? sender, EventArgs e)
{
Process proc = Process.GetCurrentProcess();
Console.WriteLine($"Dynamo exiting with Peak physical memory {proc.PeakWorkingSet64} bytes");
if (proc.HasExited)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Process is used here but System.Diagnostics is not imported, and it is not part of the SDK implicit usings set for Microsoft.NET.Sdk. Add using System.Diagnostics; (or fully-qualify System.Diagnostics.Process) to avoid a compile error.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +21
[Route("graph/run", Name = "post-graph-run")]
public new Task<GraphResult> PostGraphRun([FromBody] RunGraph body)
{
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

[Route] and [FromBody] attributes are used without any using for their defining namespace. Unless these are custom attributes re-exported by DynamoPlayer, this will not compile. Add the appropriate reference/using (typically Microsoft.AspNetCore.Mvc) or fully-qualify the attribute types.

Copilot uses AI. Check for mistakes.
Comment on lines 283 to 293
private void SubscribeApplicationEvents()
{
UIControlledApplication.Idling += OnApplicationIdle;

proxy = new EventHandlerProxy();

UIControlledApplication.ViewActivated += proxy.OnApplicationViewActivated;
UIControlledApplication.ViewActivating += proxy.OnApplicationViewActivating;
UIControlledApplication.ViewActivated += EventHandlerProxy.Instance.OnApplicationViewActivated;
UIControlledApplication.ViewActivating += EventHandlerProxy.Instance.OnApplicationViewActivating;

ControlledApplication.DocumentClosing += proxy.OnApplicationDocumentClosing;
ControlledApplication.DocumentClosed += proxy.OnApplicationDocumentClosed;
ControlledApplication.DocumentOpened += proxy.OnApplicationDocumentOpened;
ControlledApplication.DocumentClosing += EventHandlerProxy.Instance.OnApplicationDocumentClosing;
ControlledApplication.DocumentClosed += EventHandlerProxy.Instance.OnApplicationDocumentClosed;
ControlledApplication.DocumentOpened += EventHandlerProxy.Instance.OnApplicationDocumentOpened;
}
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

SubscribeApplicationEvents/UnsubscribeApplicationEvents reference EventHandlerProxy.Instance..., but EventHandlerProxy is also the name of the static property on DynamoRevitApp. Inside this class that name resolves to the property, so .Instance won’t compile. Use the fully-qualified type name (e.g. RevitServices.EventHandler.EventHandlerProxy.Instance) or rename the DynamoRevitApp.EventHandlerProxy property to avoid the identifier collision.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +17
<DebugSymbols>false</DebugSymbols>
<OutputPath>bin\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<AssemblyTitle>AssemblyInfoGenerator</AssemblyTitle>
<OutputPath>bin\$(Configuration)\</OutputPath>
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

This property group now sets DebugSymbols and OutputPath twice (lines 12 vs 14, and 13 vs 17). The earlier values will be overridden, which is easy to miss when editing build settings. Remove the duplicates and keep a single authoritative value for each property.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to 22

internal static EventHandlerProxy Instance = new();

Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

EventHandlerProxy.Instance is declared internal, but it is referenced from multiple other assemblies in this PR (e.g. DynamoRevit, RevitNodesUI, tests). As written, this will cause accessibility errors. Expose the singleton via a public static property/field (e.g. public static EventHandlerProxy Instance { get; } = new();) or add the necessary InternalsVisibleTo entries for every consuming assembly.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +53
// Use the actual production method — SetupProfilingHandlers subscribes to WorkspaceOpened
// and wires all the profiling/serialization handlers on the model we already have.
var entrypoint = new DAEntrypoint();
entrypoint.SetupProfilingHandlers(Model);

Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

This test calls entrypoint.SetupProfilingHandlers(Model), but SetupProfilingHandlers is private in DAEntrypoint, so the test will not compile. Either make SetupProfilingHandlers internal/public (and add InternalsVisibleTo for RevitSystemTests if needed) or adjust the test to exercise the behavior through a public entrypoint.

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +61
internal class DynamoRevitAssemblyResolver
{
/// <summary>
/// Handler to the ApplicationDomain's AssemblyResolve event.
/// If an assembly's location cannot be resolved, an exception is
/// thrown. Failure to resolve an assembly will leave Dynamo in
/// a bad state, so we should throw an exception here which gets caught
/// by our unhandled exception handler and presents the crash dialogue.
/// </summary>
/// <param name="dynamoCorePath"></param>
/// <param name="args"></param>
/// <returns></returns>
internal static Assembly ResolveDynamoAssembly(string dynamoCorePath, List<string> additionalPaths, ResolveEventArgs args)
{
var assemblyPath = string.Empty;
var assemblyName = new AssemblyName(args.Name).Name + ".dll";

try
{
assemblyPath = Path.Combine(dynamoCorePath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}

if (additionalPaths != null)
{
foreach (var additionalPath in additionalPaths)
{
assemblyPath = Path.Combine(additionalPath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
}
}

var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);

// Try "Dynamo 0.x\Revit_20xx" folder first...
assemblyPath = Path.Combine(assemblyDirectory, assemblyName);
if (!File.Exists(assemblyPath))
{
// If assembly cannot be found, try in "Dynamo 0.x" folder.
var parentDirectory = Directory.GetParent(assemblyDirectory);
assemblyPath = Path.Combine(parentDirectory.FullName, assemblyName);
}

return (File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
throw new Exception(string.Format("The location of the assembly, {0} could not be resolved for loading.", assemblyPath), ex);
}
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

This file is added under a path that includes spaces (Utilities/internal class DynamoRevitAssemblyResolver.cs) and the type is declared in the global namespace. Both make discovery, tooling, and future refactors harder (and the filename is likely unintentional). Rename the file to Utilities/DynamoRevitAssemblyResolver.cs and place the type under an appropriate namespace (e.g. Dynamo.Applications.Utilities).

Suggested change
internal class DynamoRevitAssemblyResolver
{
/// <summary>
/// Handler to the ApplicationDomain's AssemblyResolve event.
/// If an assembly's location cannot be resolved, an exception is
/// thrown. Failure to resolve an assembly will leave Dynamo in
/// a bad state, so we should throw an exception here which gets caught
/// by our unhandled exception handler and presents the crash dialogue.
/// </summary>
/// <param name="dynamoCorePath"></param>
/// <param name="args"></param>
/// <returns></returns>
internal static Assembly ResolveDynamoAssembly(string dynamoCorePath, List<string> additionalPaths, ResolveEventArgs args)
{
var assemblyPath = string.Empty;
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
try
{
assemblyPath = Path.Combine(dynamoCorePath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
if (additionalPaths != null)
{
foreach (var additionalPath in additionalPaths)
{
assemblyPath = Path.Combine(additionalPath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
}
}
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
// Try "Dynamo 0.x\Revit_20xx" folder first...
assemblyPath = Path.Combine(assemblyDirectory, assemblyName);
if (!File.Exists(assemblyPath))
{
// If assembly cannot be found, try in "Dynamo 0.x" folder.
var parentDirectory = Directory.GetParent(assemblyDirectory);
assemblyPath = Path.Combine(parentDirectory.FullName, assemblyName);
}
return (File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
throw new Exception(string.Format("The location of the assembly, {0} could not be resolved for loading.", assemblyPath), ex);
}
namespace Dynamo.Applications.Utilities
{
internal class DynamoRevitAssemblyResolver
{
/// <summary>
/// Handler to the ApplicationDomain's AssemblyResolve event.
/// If an assembly's location cannot be resolved, an exception is
/// thrown. Failure to resolve an assembly will leave Dynamo in
/// a bad state, so we should throw an exception here which gets caught
/// by our unhandled exception handler and presents the crash dialogue.
/// </summary>
/// <param name="dynamoCorePath"></param>
/// <param name="args"></param>
/// <returns></returns>
internal static Assembly ResolveDynamoAssembly(string dynamoCorePath, List<string> additionalPaths, ResolveEventArgs args)
{
var assemblyPath = string.Empty;
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
try
{
assemblyPath = Path.Combine(dynamoCorePath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
if (additionalPaths != null)
{
foreach (var additionalPath in additionalPaths)
{
assemblyPath = Path.Combine(additionalPath, assemblyName);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
}
}
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
// Try "Dynamo 0.x\Revit_20xx" folder first...
assemblyPath = Path.Combine(assemblyDirectory, assemblyName);
if (!File.Exists(assemblyPath))
{
// If assembly cannot be found, try in "Dynamo 0.x" folder.
var parentDirectory = Directory.GetParent(assemblyDirectory);
assemblyPath = Path.Combine(parentDirectory.FullName, assemblyName);
}
return (File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
throw new Exception(string.Format("The location of the assembly, {0} could not be resolved for loading.", assemblyPath), ex);
}
}

Copilot uses AI. Check for mistakes.

namespace Dynamo.Applications
{
internal static class ASMPrealoaderUtils
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The utility class name ASMPrealoaderUtils looks misspelled ("Prealoader" vs "Preloader"). Since this is a newly introduced type referenced across the PR, consider renaming it (and the file) to ASMPreloaderUtils for clarity and consistency.

Suggested change
internal static class ASMPrealoaderUtils
internal static class ASMPreloaderUtils

Copilot uses AI. Check for mistakes.
@pinzart90
Copy link
Copy Markdown
Collaborator Author

@pinzart90 are you looking for a review on this or just getting it spun up?

I don't think it is review-able yet

pinzart90 and others added 4 commits April 24, 2026 09:03
ISolate the DA Application class from the rest of the implementation so
that we can handle setup an Assembly resolver before all the
dependencies need to get solved.


Please Note:
1. Before submitting the PR, please review [How to Contribute to
Dynamo](https://github.com/DynamoDS/Dynamo/blob/master/CONTRIBUTING.md)
2. Dynamo Team will meet 1x a month to review PRs found on Github
(Issues will be handled separately)
3. PRs will be reviewed from oldest to newest
4. If a reviewed PR requires changes by the owner, the owner of the PR
has 30 days to respond. If the PR has seen no activity by the next
session, it will be either closed by the team or depending on its
utility will be taken over by someone on the team
5. PRs should use either Dynamo's default PR template or [one of these
other template
options](https://github.com/DynamoDS/Dynamo/wiki/Choosing-a-Pull-Request-Template)
in order to be considered for review.
6. PRs that do not have one of the Dynamo PR templates completely filled
out with all declarations satisfied will not be reviewed by the Dynamo
team.
7. PRs made to the `DynamoRevit` repo will need to be cherry-picked into
all the DynamoRevit Release branches that Dynamo supports. Contributors
will be responsible for cherry-picking their reviewed commits to the
other branches after a `LGTM` label is added to the PR.

### Purpose

(FILL ME IN) This section describes why this PR is here. Usually it
would include a reference
to the tracking task that it is part or all of the solution for.

### Declarations

Check these if you believe they are true

- [ ] The code base is in a better state after this PR
- [ ] Is documented according to the
[standards](https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards)
- [ ] The level of testing this PR includes is appropriate
- [ ] User facing strings, if any, are extracted into `*.resx` files
- [ ] Snapshot of UI changes, if any.

### Reviewers

(FILL ME IN) Reviewer 1  (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

### FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of
https://jira.autodesk.com/browse/DYN-10310
Cannot save rvt after running graph

Check these if you believe they are true

- [ ] The code base is in a better state after this PR
- [ ] Is documented according to the
[standards](https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards)
- [ ] The level of testing this PR includes is appropriate
- [ ] User facing strings, if any, are extracted into `*.resx` files
- [ ] Snapshot of UI changes, if any.

(FILL ME IN) Reviewer 1  (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

(FILL ME IN, Optional) Names of anyone else you wish to be notified of
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants