Libraries Reference
The Power Platform Developer Suite (PPDS) ships a set of focused .NET libraries you can compose in your own applications. PPDS.Auth resolves credentials, PPDS.Dataverse manages connection pools and bulk operations on top of that, PPDS.Migration layers dependency-aware export and import on top of the pool, and PPDS.Plugins is a standalone net462 package of attributes for declarative plugin registration. The CLI, MCP server, and VS Code extension are all built on these same libraries.
Packages
| Package | Published stable version | Target | Description |
|---|---|---|---|
PPDS.Auth | 1.1.2 | net8.0;net9.0;net10.0 | Credential providers, auth profiles, DPAPI-encrypted credential store |
PPDS.Dataverse | 1.3.2 | net8.0;net9.0;net10.0 | Connection pooling, bulk operations, throttle-aware resilience |
PPDS.Migration | 1.2.2 | net8.0;net9.0;net10.0 | Parallel exporter and tiered importer over CMT-format archives |
PPDS.Plugins | 3.0.1 | net462 | Declarative attributes for plugin steps, images, and Custom APIs |
PPDS.Query | 1.0.2 | net8.0;net9.0;net10.0 | SQL engine, FetchXML translation, and ADO.NET provider |
Versions above were verified from public packages on October 30, 2026. See the maintenance release notes for the changes and validation scope.
PPDS.Plugins targets net462 as a compatibility baseline; plugin consumers
can target .NET Framework 4.6.2 through 4.8. The CLI's accepted package asset
groups are a separate deployment constraint; see plugin packages.
The other libraries target .NET 8, 9, and 10.
PPDS.Auth
Handles credential acquisition, profile storage, and token caching. Profiles are persisted to disk with DPAPI encryption on Windows and platform keychain integration on other OSes.
Installation
dotnet add package PPDS.Auth
Key types
| Type | Purpose |
|---|---|
ICredentialProvider | Abstraction over all auth flows; returns authenticated ServiceClient |
CredentialProviderFactory | Builds an ICredentialProvider from an AuthProfile |
AuthMethod | Enum of supported flows (9 total — see below) |
AuthProfile | Serialized profile with environment URL, tenant, and auth method |
ProfileStore | File-backed profile collection |
ISecureCredentialStore / NativeCredentialStore | Platform-specific secret storage |
ProfileEncryption | DPAPI wrapper used by the profile store |
IGlobalDiscoveryService | Resolves Dataverse environments via Global Discovery |
Supported AuthMethod values: InteractiveBrowser, DeviceCode, ClientSecret, CertificateFile, CertificateStore, ManagedIdentity, GitHubFederated, AzureDevOpsFederated, UsernamePassword.
Usage
Register the shared singletons in DI, then create a provider from a profile:
using Microsoft.Extensions.DependencyInjection;
using PPDS.Auth.Credentials;
using PPDS.Auth.DependencyInjection;
using PPDS.Auth.Profiles;
var services = new ServiceCollection();
services.AddAuthServices();
var provider = services.BuildServiceProvider();
var profileStore = provider.GetRequiredService<ProfileStore>();
var credentialStore = provider.GetRequiredService<ISecureCredentialStore>();
var profile = profileStore.Get("dev");
using var credentials = await CredentialProviderFactory.CreateAsync(profile, credentialStore);
using var client = await credentials.CreateServiceClientAsync(profile.EnvironmentUrl);
AddAuthServices registers ProfileStore, EnvironmentConfigStore, and ISecureCredentialStore as singletons. They are file-backed and intended to be shared for the lifetime of the process.
PPDS.Dataverse
Connection pooling, bulk operation wrappers, throttle detection, and metadata queries over the Dataverse SDK. Pool connections are keyed by application user, and the pool tracks live degrees-of-parallelism hints from each connection so multi-tenant batch workloads stay within service-protection limits.
Installation
dotnet add package PPDS.Dataverse
Key types
| Type | Purpose |
|---|---|
IDataverseConnectionPool | Checkout-based pool with DOP tracking, throttle retries, and ExecuteAsync helper |
IPooledClient | Scoped pool checkout — returns to pool on dispose |
DataverseOptions / DataverseConnection | Configuration shape for the pool |
IBulkOperationExecutor | CreateMultiple / UpdateMultiple / UpsertMultiple / DeleteMultiple wrappers |
IMetadataQueryService | Cached entity and attribute metadata |
IQueryExecutor | Query execution with pagination |
IThrottleTracker | Per-connection throttle state |
Usage
using Microsoft.Extensions.DependencyInjection;
using PPDS.Dataverse.BulkOperations;
using PPDS.Dataverse.Configuration;
using PPDS.Dataverse.DependencyInjection;
using PPDS.Dataverse.Pooling;
var services = new ServiceCollection();
services.AddDataverseConnectionPool(options =>
{
options.Connections.Add(new DataverseConnection("Primary", connectionString));
options.Pool.MaxPoolSize = 50;
});
var provider = services.BuildServiceProvider();
var pool = provider.GetRequiredService<IDataverseConnectionPool>();
var bulk = provider.GetRequiredService<IBulkOperationExecutor>();
await pool.EnsureInitializedAsync();
var result = await bulk.CreateMultipleAsync(
entityLogicalName: "contact",
entities: contacts,
options: new BulkOperationOptions { BatchSize = 1000 });
AddDataverseConnectionPool has an overload that binds from IConfiguration, including multi-environment configs — see the XML docs on ServiceCollectionExtensions for the full configuration schema.
PPDS.Migration
Parallel export and dependency-ordered import over CMT-format ZIP archives. Migration does not take raw connection strings — it resolves IExporter and IImporter from DI on top of a PPDS.Dataverse connection pool.
Installation
dotnet add package PPDS.Migration
Key types
| Type | Purpose |
|---|---|
IExporter (default: ParallelExporter) | Reads a schema and writes a CMT ZIP |
IImporter (default: TieredImporter) | Dependency-graph import with resumable phases |
ExportOptions / ImportOptions | Parallelism, bypass flags, date shifting, user mapping |
ISchemaGenerator | Builds a MigrationSchema from Dataverse metadata |
IProgressReporter | Streams phase and entity progress |
ExportResult / ImportResult | Counts, warnings, errors, timing |
IExporter.ExportAsync takes (string schemaPath, string outputPath, ExportOptions? options, IProgressReporter? progress, CancellationToken cancellationToken) and returns Task<ExportResult>. IImporter.ImportAsync takes (string dataPath, ImportOptions? options, IProgressReporter? progress, CancellationToken cancellationToken) and returns Task<ImportResult>. Both interfaces also expose overloads that take pre-parsed MigrationSchema / MigrationData + ExecutionPlan for reuse across multiple runs.
Usage
using Microsoft.Extensions.DependencyInjection;
using PPDS.Dataverse.Configuration;
using PPDS.Dataverse.DependencyInjection;
using PPDS.Migration.DependencyInjection;
using PPDS.Migration.Export;
using PPDS.Migration.Import;
var services = new ServiceCollection();
services.AddDataverseConnectionPool(options =>
{
options.Connections.Add(new DataverseConnection("Primary", connectionString));
});
services.AddDataverseMigration();
var provider = services.BuildServiceProvider();
var exporter = provider.GetRequiredService<IExporter>();
var importer = provider.GetRequiredService<IImporter>();
var exportResult = await exporter.ExportAsync(
schemaPath: "./schema.xml",
outputPath: "./export/data.zip",
options: new ExportOptions { MaxDegreeOfParallelism = 8 });
var importResult = await importer.ImportAsync(
dataPath: "./export/data.zip",
options: new ImportOptions { BypassCustomPluginExecution = true });
AddDataverseMigration throws InvalidOperationException if AddDataverseConnectionPool has not been called first — the importer and exporter require a registered IDataverseConnectionPool.
PPDS.Plugins
Attribute-based plugin registration. Decorate your plugin classes and the CLI (or your own tooling) reads the attributes to register steps, images, and Custom APIs against Dataverse. The package retains its net462 compatibility target for .NET Framework plugin projects.
Installation
dotnet add package PPDS.Plugins
Attributes and enums
| Type | Purpose |
|---|---|
PluginStepAttribute | Message, entity, stage, mode, filtering, impersonation, bypass, invocation source |
PluginImageAttribute | Pre/post images, attributes, entity alias, step linkage |
CustomApiAttribute | Custom API unique name, binding, function/action, privilege |
CustomApiParameterAttribute | Request/response parameters for a Custom API |
PluginStage, PluginMode, PluginImageType | Step configuration enums |
PluginDeployment, PluginInvocationSource | Deployment target and pipeline source (new in 2.1) |
ApiBindingType, ApiParameterType, ParameterDirection, ApiProcessingStepType | Custom API enums (new in 2.1) |
Compatibility with 2.x
PluginStepAttribute gained Deployment, RunAsUser, CanBeBypassed, CanUseReadOnlyConnection, and InvocationSource properties. CustomApiAttribute and CustomApiParameterAttribute add full Custom API authoring. These additions are source-compatible with 2.x. Version 3.0.0 changed the strong-name identity: consumers bound to the old public key token must rebuild against 3.x. See the Plugins changelog.
Usage
using Microsoft.Xrm.Sdk;
using PPDS.Plugins;
[PluginStep(
Message = "Update",
EntityLogicalName = "account",
Stage = PluginStage.PostOperation,
Mode = PluginMode.Synchronous,
FilteringAttributes = "name,telephone1",
CanUseReadOnlyConnection = false)]
[PluginImage(
ImageType = PluginImageType.PreImage,
Name = "PreImage",
Attributes = "name,telephone1,revenue")]
public class AccountUpdatePlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// context.PreEntityImages["PreImage"] is populated by the registered image
}
}
[CustomApi(
UniqueName = "ppds_ProcessOrder",
DisplayName = "Process Order",
BindingType = ApiBindingType.Global)]
[CustomApiParameter(
Name = "OrderId",
Type = ApiParameterType.Guid,
Direction = ParameterDirection.Input)]
[CustomApiParameter(
Name = "ConfirmationNumber",
Type = ApiParameterType.String,
Direction = ParameterDirection.Output)]
public class ProcessOrderPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider) { /* ... */ }
}
PPDS.Query
The query library translates SQL to FetchXML and executes queries through the
Dataverse connection pool. Its ADO.NET provider exposes PpdsDbConnection,
PpdsDbCommand, and PpdsDbDataReader in PPDS.Query.Provider.
dotnet add package PPDS.Query
See the Query library guide and examples.
Versioning
Each library is versioned independently and follows semantic versioning. PPDS.Plugins is on the stable 3.x line; Auth, Dataverse, Migration, and Query each have their own stable 1.x line. The PPDS CLI pins specific library versions per release, so upgrading the CLI is the simplest way to stay on a known-good set.
Breaking changes are listed in each package's CHANGELOG.md in the main repo: PPDS.Auth, PPDS.Dataverse, PPDS.Migration, PPDS.Plugins, PPDS.Query.
Next steps
- Authentication guide — profile creation and credential flows
- CLI reference — commands built on these libraries