Need a statistics library, a PDF renderer, or a cloud SDK in your node type? You don't have to redeploy the portal to get it. Drop a #r "nuget:..." directive at the top of any .cs file under the node type's Source/ folder and the compiler restores the package in-process before building.

This mechanism works in two places:

Where What happens
Source/*.cs files in a node type Package resolves at node-type compilation time
Interactive markdown code cells Package resolves before the kernel compiles the cell

Both routes go through the same NuGetAssemblyResolver. See also NuGet Packages for the interactive-markdown side of the story. Source/*.cs #r "nuget:Pkg, 1.0" Interactive Markdown cell NuGetAssembly Resolver In-Memory Cache (Id, VersionRange) NuGet Feed api.nuget.org Disk Package ~/.nuget/packages AssemblyLoad Context NuGet resolution flow — dashed = cache hit skips feed

NuGet assembly resolution: both Source files and interactive cells share one NuGetAssemblyResolver; resolved assemblies are loaded into a per-node AssemblyLoadContext.


The directive

Place #r "nuget:..." at the very top of any .cs file, before using statements:

#r "nuget:MathNet.Numerics, 5.0.0"

using MathNet.Numerics.LinearAlgebra;

public record MatrixDemo
{
    public double[,] Data { get; init; } = { { 1, 2 }, { 3, 4 } };

    public double Determinant() =>
        Matrix<double>.Build.DenseOfArray(Data).Determinant();
}

Always pin a specific version. #r "nuget:MathNet.Numerics" without a version resolves "latest" at compile time — that makes your node type non-reproducible and may silently pick up a breaking change.


End-to-end example

The following walks through a complete node type that uses MathNet.Numerics to compute the inverse of a 2×2 matrix and renders the result as a layout area.

Folder layout

samples/Graph/Data/
  MathDemo/
    Matrix.json              # NodeType definition
    Matrix/
      Source/
        Matrix.cs            # Content record — references MathNet
        MatrixLayoutAreas.cs # Layout area that calls MathNet

Source/Matrix.cs

// <meshweaver>
// Id: Matrix
// DisplayName: Matrix
// </meshweaver>
#r "nuget:MathNet.Numerics, 5.0.0"

using MathNet.Numerics.LinearAlgebra;
using MeshWeaver.Domain;

public record Matrix
{
    [Required]
    [MeshNodeProperty(nameof(MeshNode.Name))]
    public string Name { get; init; } = string.Empty;

    public double A11 { get; init; } = 1;
    public double A12 { get; init; } = 2;
    public double A21 { get; init; } = 3;
    public double A22 { get; init; } = 4;

    public double Determinant()
    {
        var m = Matrix<double>.Build.DenseOfArray(new[,]
        {
            { A11, A12 },
            { A21, A22 }
        });
        return m.Determinant();
    }
}

Source/MatrixLayoutAreas.cs

// <meshweaver>
// Id: MatrixLayoutAreas
// DisplayName: Matrix Layout Areas
// </meshweaver>
#r "nuget:MathNet.Numerics, 5.0.0"

using MathNet.Numerics.LinearAlgebra;
using MeshWeaver.Layout;
using MeshWeaver.Layout.Composition;
using MeshWeaver.Messaging;

public static class MatrixLayoutAreas
{
    public static MessageHubConfiguration AddMatrixLayoutAreas(this MessageHubConfiguration config)
        => config.AddLayout(layout => layout.WithView("Inverse", Inverse));

    public static UiControl Inverse(LayoutAreaHost host, RenderingContext _)
    {
        var m = Matrix<double>.Build.DenseOfArray(new[,]
        {
            { 1.0, 2.0 },
            { 3.0, 4.0 }
        });
        var inv = m.Inverse();
        return Controls.Markdown($"""
            **Matrix:**
            ```
            {m}
            ```
            **Inverse:**
            ```
            {inv}
            ```
            """);
    }
}

Pin the same package version across every Source/ file that uses it. Each file is resolved independently, so mismatched versions produce conflicting assemblies.

Matrix.json

{
  "id": "Matrix",
  "namespace": "MathDemo",
  "name": "Matrix",
  "nodeType": "NodeType",
  "content": {
    "$type": "NodeTypeDefinition",
    "namespace": "MathDemo",
    "displayName": "Matrix",
    "configuration": "config => config
      .WithContentType<Matrix>()
      .AddLayout(layout => layout
        .AddMatrixLayoutAreas()
        .WithDefaultArea(\"Inverse\"))"
  }
}

See it run

The deployed sample lives at MathDemo/Matrix/Example. Its Inverse layout area — compiled from Source/ with the #r "nuget:MathNet.Numerics, 5.0.0" directive — is embedded directly below:

@Doc/DataMesh/NodeTypeWithNuGet/MathDemo/Matrix/Example/Inverse

Here is the equivalent interactive-markdown cell: same NuGet directive, same MathNet call, executed by the kernel every time this page loads:

#r "nuget:MathNet.Numerics, 5.0.0"
using MathNet.Numerics.LinearAlgebra;

var m = Matrix<double>.Build.DenseOfArray(new double[,] { { 1, 2 }, { 3, 4 } });
var inv = m.Inverse();
Controls.Markdown($"""
**Matrix**
```
{m}
```
**Inverse**
```
{inv}
```
**Determinant:** {m.Determinant()}
""")

On a fresh replica the first of the two pays the single MathNet restore; the second hits the in-memory cache instantly. Both use the same NuGetAssemblyResolver under the hood.


Caching

The resolver maintains an in-memory cache keyed by the sorted (Id, VersionRange) tuple. Within a single portal process, every subsequent compilation that names the same packages reuses the already-resolved assembly list — no repeat HTTP calls.

Across restarts, the NuGet package folder on disk ($NUGET_PACKAGES, default ~/.nuget/packages) provides a second caching layer. Only a fresh replica on a fresh ACA node triggers a real download.


Deployment — no .NET SDK required

The resolver is built on the public NuGet.Protocol, NuGet.Packaging, and NuGet.Resolver libraries. It does not invoke dotnet restore, does not need MSBuild, and runs on the plain mcr.microsoft.com/dotnet/aspnet runtime image. ACA needs only:


Transitive dependencies at runtime

NuGet packages often pull in transitive assemblies that aren't referenced by your code at compile time but are loaded later by the main package. The node's AssemblyLoadContext is extended with a probing directory list pointing at every lib/<tfm>/ folder of every resolved package, so those loads succeed without extra configuration.


Failure modes

Symptom Cause Fix
NuGet error naming the package id Unknown package id — likely a typo Check the exact id on nuget.org and retry
NuGet error listing available versions No matching version Pin a version that exists on the feed
Timeout from NuGet protocol Network blocked Verify ACA egress policy and that NUGET_PACKAGES is writable
"type not found" at compilation Package has no .NET Standard / .NET 8/10 asset The resolver uses FrameworkReducer.GetNearest; if no compatible TFM exists, no DLLs are returned — pick a different package or version

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.