XrmGhost.Attributes 1.0.2

dotnet add package XrmGhost.Attributes --version 1.0.2
                    
NuGet\Install-Package XrmGhost.Attributes -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XrmGhost.Attributes" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XrmGhost.Attributes" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="XrmGhost.Attributes" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XrmGhost.Attributes --version 1.0.2
                    
#r "nuget: XrmGhost.Attributes, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XrmGhost.Attributes@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XrmGhost.Attributes&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=XrmGhost.Attributes&version=1.0.2
                    
Install as a Cake Tool

XrmGhost.Attributes

XrmGhost.Attributes is a .NET library of custom attributes for declarative Dataverse plugin development. Decorate your plugin classes with these attributes to declare execution context, message handling, entity images, input/output parameters, and configuration — without writing plumbing code.

The package targets netstandard2.0 and has no runtime dependencies beyond the BCL, so it can be referenced by any Dataverse plugin project.

Current version: 0.6.27


Table of Contents

  1. Standalone Use
  2. XrmGhost Ecosystem
  3. Installation
  4. Included Attributes
  5. Usage Examples
  6. Contributing

Standalone Use

You can reference XrmGhost.Attributes in any Dataverse plugin project — no other XrmGhost component is required.

The attributes are pure .NET attribute classes. Adding them to your plugin decorates the assembly with structured metadata that can be read at runtime or build time via reflection. On their own they impose zero runtime overhead inside the Dataverse sandbox: a [PreImage] or [InputParameter] attribute on a class does nothing unless something reads it.

Typical standalone uses:

  • Custom tooling. Write a registration or scaffolding tool that reads attributes to automate plugin step registration.
  • Documentation generation. Produce an audit of all messages, entities, and images a plugin assembly handles, without parsing code.
  • Test harnesses. Read [InputParameter] and [PreImage] attributes to reconstruct a plausible IPluginExecutionContext in unit tests.

XrmGhost Ecosystem

Within the XrmGhost ecosystem this package is consumed by two components:

xrmghost-framework-host

xrmghost-framework-host is a thin hosting layer that wraps plugin execution. At runtime it reads the attributes on a plugin class via reflection and automatically populates the corresponding properties before calling Execute. This removes the standard boilerplate of extracting Target, pre/post images, and configuration strings from IPluginExecutionContext.

xrmghost-cli — generate-scenario

The generate-scenario command of the XrmGhost CLI introspects a plugin assembly and generates test scenario files. It uses the attribute values (entity JSON, parameter JSON, image aliases) as the starting data for each scenario.

Note: generate-scenario expects plugins to be decorated with XrmGhost.Attributes attributes. If the attributes are absent the CLI degrades gracefully with a warning, but no scenario data will be pre-populated.


Installation

1. Configure the GitHub Packages NuGet source

XrmGhost.Attributes is published to GitHub Packages. You must add the source before installing:

dotnet nuget add source https://nuget.pkg.github.com/xrmghost/index.json \
    --name github-xrmghost \
    --username YOUR_GITHUB_USERNAME \
    --password YOUR_GITHUB_PAT

Replace YOUR_GITHUB_USERNAME with your GitHub username and YOUR_GITHUB_PAT with a Personal Access Token that has the read:packages scope.

2. Add the package

dotnet add package XrmGhost.Attributes --version 0.6.27

Or add the reference directly to your .csproj:

<PackageReference Include="XrmGhost.Attributes" Version="0.6.27" />

Included Attributes

All attributes target AttributeTargets.Class — they must be placed on the plugin class, not on individual members.

Attribute Description
PluginExecutionConfigAttribute Declares entity + messages the plugin handles; supports stage, mode, and impersonation. Repeatable.
HandlesMessageAttribute Declares a single SDK message the plugin handles. Repeatable.
InputParameterAttribute Declares an input parameter name and its default JSON value. Repeatable.
OutputParameterAttribute Declares an expected output parameter name and its expected JSON value. Repeatable.
PreImageAttribute Declares a pre-operation entity image alias and its JSON seed value. Repeatable.
PostImageAttribute Declares a post-operation entity image alias and its JSON seed value. Repeatable.
SecureConfigurationAttribute Declares the default secure configuration string. Single use.
UnsecureConfigurationAttribute Declares the default unsecure configuration string. Single use.
SharedVariableAttribute Declares a shared variable name and its default JSON value. Repeatable.
SolutionComponentAttribute Declares which solution(s) the plugin should be registered in. Repeatable.

Usage Examples

All attributes live in the XrmGhost.Attributes namespace.

Basic plugin — single entity, multiple messages

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("account", "Create", "Update")]
[PreImageAttribute("primary", "{ \"__entityName\": \"account\", \"accountid\": \"00000000-0000-0000-0000-000000000001\", \"name\": \"Old Name\" }")]
[InputParameterAttribute("Target", "{ \"__entityName\": \"account\", \"accountid\": \"00000000-0000-0000-0000-000000000001\" }")]
public class AccountPlugin : IPlugin
{
    public Entity TargetEntity { get; set; }
    public Entity PreImageEntity { get; set; }

    public void Execute(IServiceProvider serviceProvider)
    {
        // When used with xrmghost-framework-host, TargetEntity and PreImageEntity
        // are populated automatically before Execute is called.
    }
}

Multiple entities and messages

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("account", "Create", "Update")]
[PluginExecutionConfigAttribute("contact", "Create")]
[PluginExecutionConfigAttribute("opportunity", "Update", "Delete")]
[InputParameterAttribute("Target", "{ \"__entityName\": \"account\", \"accountid\": \"00000000-0000-0000-0000-000000000001\" }")]
public class MultiEntityPlugin : IPlugin
{
    public Entity TargetEntity { get; set; }

    public void Execute(IServiceProvider serviceProvider)
    {
        // Registered for:
        //   Account   — Create, Update
        //   Contact   — Create
        //   Opportunity — Update, Delete
    }
}

Column-filtered entity images

Filtering images to specific columns improves performance by reducing the payload transmitted to the plugin.

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("account", "Update")]
[InputParameterAttribute("Target", "{ \"__entityName\": \"account\", \"accountid\": \"00000000-0000-0000-0000-000000000001\" }")]
[PreImageAttribute("primary", "{ \"__entityName\": \"account\", \"name\": \"Old Name\", \"revenue\": 1000.00 }",
    Attributes = new[] { "name", "accountid", "createdon", "revenue" })]
[PostImageAttribute("updated", "{ \"__entityName\": \"account\", \"name\": \"New Name\", \"revenue\": 2000.00 }",
    Attributes = new[] { "name", "modifiedon", "revenue" })]
public class AccountUpdatePlugin : IPlugin
{
    public Entity TargetEntity { get; set; }
    public Entity PreImageEntity { get; set; }
    public Entity PostImageEntity { get; set; }

    public void Execute(IServiceProvider serviceProvider) { }
}

Stage, mode, and user impersonation

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("lead", "Create", "Update",
    Stage = 20, Mode = 0,
    ImpersonatingUserId = "12345678-1234-1234-1234-123456789012")]
[SolutionComponentAttribute("LeadManagement")]
[InputParameterAttribute("Target", "{ \"__entityName\": \"lead\", \"leadid\": \"00000000-0000-0000-0000-000000000002\" }")]
public class LeadProcessorPlugin : IPlugin
{
    public Entity TargetEntity { get; set; }

    public void Execute(IServiceProvider serviceProvider) { }
}

Stage values: 10 PreValidation · 20 PreOperation · 40 PostOperation.
Mode values: 0 Synchronous · 1 Asynchronous.

Multiple solutions

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[SolutionComponentAttribute("CoreCRM", IsDefault = true)]
[SolutionComponentAttribute("SalesEnhancements")]
[PluginExecutionConfigAttribute("opportunity", "Create", "Update", "Delete")]
[InputParameterAttribute("Target", "{ \"__entityName\": \"opportunity\", \"opportunityid\": \"00000000-0000-0000-0000-000000000003\" }")]
public class OpportunityPlugin : IPlugin
{
    public Entity TargetEntity { get; set; }

    public void Execute(IServiceProvider serviceProvider) { }
}

Input and output parameters with shared variables

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("none", "CalculatePrice")]
[InputParameterAttribute("Quantity", "5")]
[InputParameterAttribute("UnitPrice", "19.99")]
[OutputParameterAttribute("TotalPrice", "99.95")]
[SharedVariableAttribute("PricingRuleVersion", "\"v2\"")]
public class CalculatePricePlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider) { }
}

Secure and unsecure configuration

using XrmGhost.Attributes;
using Microsoft.Xrm.Sdk;

[PluginExecutionConfigAttribute("account", "Create")]
[SecureConfigurationAttribute("{ \"apiKey\": \"secret-value\" }")]
[UnsecureConfigurationAttribute("{ \"endpoint\": \"https://example.com/api\" }")]
public class ConfiguredPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider) { }
}

Contributing

Contributions are welcome. Please refer to CONTRIBUTING.md for guidelines.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.0.2 106 5/7/2026
1.0.1 297 5/7/2026