Dependencies & isolation
Dependencies & isolation
Which assemblies the platform provides, when a third-party library belongs next to your plugin, and how each plugin's load context resolves its references.
On this page
What the platform provides and what you ship
The SabrTrader.Sdk meta-package brings in the contract assemblies you compile against.
The platform ships those assemblies itself, so you reference them at build time and leave them out of
the plugin folder:
| Assembly | Provided by the platform? | Deploy with your plugin? |
|---|---|---|
SabrTrader.Pipeline.Contracts |
Yes | No |
SabrTrader.Pipeline.Venues.Contracts |
Yes | No |
SabrTrader.Pipeline.Strategies.Contracts |
Yes | No |
SabrTrader.Pipeline.AddOns.Contracts |
Yes | No |
| The .NET runtime / framework assemblies | Yes | No |
| A library the platform does not ship (a CSV parser, an exchange SDK) | No | Yes |
| A library the platform also ships | Yes | No. Your plugin gets the platform's copy (see Versions). |
| Your own plugin DLL | Not applicable | Yes |
SabrTrader.* and .NET framework assemblies come
from the platform. Third-party libraries that only your plugin uses go next to your plugin DLL.
Third-party dependencies
If your plugin references a library the platform does not ship, copy that library's DLL into the
plugin folder next to your plugin DLL. Your plugin's load context resolves it from the plugin folder:
through your plugin's .deps.json when one is present, otherwise by file name
(<assembly name>.dll). A NuGet package can bring more than one DLL; copy each one your
plugin uses.
DeploySabrTraderPlugin target copies $(TargetPath) (your DLL) and its PDB,
not your dependencies. Copy a third-party DLL into the plugin folder yourself, or add your own copy
step to the project.
The plugin folder is flat and shared by every plugin, and every DLL in it is also inspected as a candidate plugin. A library DLL registers nothing, so this costs only load time.
The isolation model
Each plugin DLL is loaded into its own collectible AssemblyLoadContext, named
Plugin:<file name>. A library your plugin loads from the plugin folder lives in that
context, so its statics are private to your plugin, and one plugin's dependencies stay out of
another's. When your plugin references an assembly, its load context resolves the reference in this
order:
- Assemblies the platform ships resolve to the platform's copy. This covers the SDK contract assemblies, the .NET framework, and every other library in the platform's installation folder.
-
Anything else is loaded from the plugin folder into your plugin's own context, through your
plugin's
.deps.jsonwhen present, otherwise by file name.
At startup the platform loads every DLL in the folder this way, catalogs its types, and writes a summary line plus any load or registration errors to the Control Center Log tab. A malformed DLL, a missing dependency or a type that fails to register is logged, and the rest of the platform continues. Reloads of a changed DLL follow the same path in a fresh load context.
Why contracts come from the platform
The platform and your plugin have to agree on the contract types: IIndicator,
Strategy, IVenuePlugin and the rest. In .NET a type's identity is its name plus
the assembly instance it was loaded from. If a contract assembly were loaded a second time inside your
plugin's context, the runtime would hold two IIndicator types that look identical but are
not interchangeable, and the platform would not recognise your indicator.
The first rule in the resolution order prevents this: every contract reference resolves to the
platform's own assembly, so typeof(IIndicator) is the same type object on both sides.
Contract copies in the plugin folder are never used for this, which is why there is no reason to ship
them. Your private third-party libraries have no shared-identity requirement, so they load inside your
plugin's context from the plugin folder.
Versions & targeting
-
Target framework. The SDK assemblies target
net10.0and the platform runs on .NET 10, so your plugin targetsnet10.0. - Libraries the platform ships win. When the platform ships a library your plugin also uses, your plugin runs against the platform's version whenever that version is at least the one you compiled against. Compile against a version at or below the platform's, and test against the platform release you target.
-
One file name per library. The plugin folder is shared by all plugins, so it can hold only
one
Library.dll. Two plugins that need different versions of the same third-party library cannot both ship it; agree on one version. - SDK version. A plugin compiled against an SDK version runs on a platform that ships that contract version or a compatible later one. Rebuild against the SDK version that matches the platform release you target.