AzureTray.Plugin.Contracts
1.3.0
dotnet add package AzureTray.Plugin.Contracts --version 1.3.0
NuGet\Install-Package AzureTray.Plugin.Contracts -Version 1.3.0
<PackageReference Include="AzureTray.Plugin.Contracts" Version="1.3.0" />
<PackageVersion Include="AzureTray.Plugin.Contracts" Version="1.3.0" />
<PackageReference Include="AzureTray.Plugin.Contracts" />
paket add AzureTray.Plugin.Contracts --version 1.3.0
#r "nuget: AzureTray.Plugin.Contracts, 1.3.0"
#:package AzureTray.Plugin.Contracts@1.3.0
#addin nuget:?package=AzureTray.Plugin.Contracts&version=1.3.0
#tool nuget:?package=AzureTray.Plugin.Contracts&version=1.3.0
AzureTray.Plugin.Contracts
The SDK package for building AzureTray plugins. Reference this package to implement ITrayPlugin and ship a plugin the host can load.
What's inside
ITrayPlugin— the top-level plugin contract.IPluginContext— services the host hands to the plugin at initialization (logger, HTTP factory, clipboard, notifier, tenant list, badge surface, etc.).PluginMenuItem,PluginPermissionRequirement,PluginOption,PluginTest,PluginTenant,NotificationRequest/NotificationResult— the supporting data types.PluginApiVersion— the contract version your plugin must declare it was built against.
Minimum plugin csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>true</IsPackable>
<PackageId>YourOrg.AzureTray.Plugin.YourPlugin</PackageId>
<PackageTags>proxylayer.azuretray-plugin;your;tags</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AzureTray.Plugin.Contracts" Version="1.2.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Packaging & deployment
1. Add the required project property
Add <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to your <PropertyGroup>. This copies every transitive NuGet dependency into the build output so the host can resolve them at runtime without a global package cache.
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
...
</PropertyGroup>
2. Publish (recommended) or build
# Produces a self-contained output folder with a .deps.json — the preferred path.
dotnet publish YourPlugin.csproj -c Release -o ./out
# A plain build also works; the host falls back to sibling-DLL resolution
# when no .deps.json is present.
dotnet build YourPlugin.csproj -c Release
Do not ship AzureTray.Plugin.Contracts.dll in the output — the PrivateAssets="all" reference in your .csproj already excludes it. The host loads its own copy of that assembly; a second copy causes a type-identity mismatch and the ITrayPlugin cast silently fails.
3. Install into the plugins folder
The host scans %LOCALAPPDATA%\AzureTray.Data\plugins\ at startup using two layouts:
| Layout | When to use | Steps |
|---|---|---|
| Subfolder (recommended) | Any plugin with transitive deps | Create plugins\<YourPackageId>\, copy your publish output there. The main DLL must be named <folder-name>.dll (e.g. plugins\Acme.Plugin.Foo\Acme.Plugin.Foo.dll). |
| Flat (legacy) | Single-DLL plugins with no private deps | Drop YourPlugin.dll directly in plugins\. |
For the subfolder layout the loader first tries plugins\<folder>\<folder>.dll; if that name doesn't exist it scans for any DLL in the folder that contains an ITrayPlugin implementation. Framework assemblies whose name starts with System., Microsoft., Azure., or Newtonsoft. are skipped during the scan.
4. Runtime trust mode
The default trust mode is AllowUnsigned (development). For your own testing this means no signing is needed. Deployments configured with RequireSigned or RequireTrustedPublisher will reject the plugin unless it carries a valid Authenticode signature.
Version gate
Plugins declare ITrayPlugin.ApiVersion (the PluginApiVersion.Current value they were built against). The host loads a plugin when that value falls within its supported range [PluginApiVersion.MinSupported, PluginApiVersion.Current]; anything outside the range is rejected with a logged message naming the range. Use PluginApiVersion.IsSupported(int) to test a value.
Because the contracts assembly keeps a fixed AssemblyVersion, an old plugin always binds to the host's current contracts copy at runtime — the range is the only thing that decides whether that copy will load it.
How the range moves:
- Additive, binary-compatible changes (a new default-interface member, a new optional capability interface, a new init-only property on a record) bump
Currentand leaveMinSupportedalone. Plugins built against any version still in the window keep loading — so you can build against an older API and keep running on newer hosts. - Breaking changes raise
MinSupported, intentionally locking out the now-incompatible older plugins. These should be rare; prefer the additive techniques above.
To run a single plugin binary across a span of hosts, build against the lowest API you need and feature-detect newer host capabilities at runtime via IPluginContext.HostVersion.
More
See CONTRIBUTING.md in the host repo for the full plugin author guide, including how to submit a plugin to the curated registry the in-app browser pulls from.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 118 | 5/28/2026 |
| 1.2.0 | 106 | 5/27/2026 |
| 1.0.0 | 96 | 5/20/2026 |
| 0.2.0 | 101 | 5/12/2026 |
| 0.2.0-preview.202605120535 | 54 | 5/12/2026 |