TALXIS.DevKit.Templates.Dataverse
1.16.0
Prefix Reserved
See the version list below for details.
dotnet new install TALXIS.DevKit.Templates.Dataverse::1.16.0
Power Platform .NET Templates
This project is currently in a development phase and not ready for production use. While we actively use these tools internally, our aim is to share and collaborate with the broader community to refine and enhance their capabilities. We are in the process of gradually open-sourcing the code, removing internal dependencies to make it universally applicable. At this stage, it serves as a source of inspiration and a basis for collaboration. We welcome feedback, suggestions, and contributions through pull requests.
If wish to use this project for your team, please contact us at hello@networg.com for a personalized onboarding experience and customization to meet your specific needs.
Only use this if you understand the standard platform customization capabilities. Using these templates with parameter combinations other than those documented here might generate invalid source code, which could still be importable to Dataverse. In some situations, this could cause your environment to become irreversibly corrupted.
Goal
The primary objective of this NuGet package is to help Power Platform developers scaffold Power Platform components using a code-first approach.
Guide
You can refer to a VS Code snippets file used by @TomProkop for conference demos.
Dev machine setup
# If you're using .NET CLI for the first time, you might need to set up nuget.org as a package source
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
# Install PowerShell 7+ to have "pwsh" executable present in your terminal
# To support running the templates cross-platform "pwsh" is used instead of "powershell.exe"
# You can use other installation methods
dotnet tool install --global PowerShell
# Install the template package to your machine
dotnet new install TALXIS.DevKit.Templates.Dataverse
Templates
Solutions
Template commands are designed to be run in the folder where *.*proj is located. Use --output parameter if your working directory is different.
Initialize a new empty solution:
dotnet new pp-solution `
--output "src/Solutions.DataModel" `
--PublisherName "tomas" `
--PublisherPrefix "tom" `
--allow-scripts yes
Tables
Create a new standard table:
dotnet new pp-entity `
--output "src/Solutions.DataModel" `
--Behavior New `
--PublisherPrefix "tom" `
--LogicalName "location" `
--LogicalNamePlural "locations" `
--DisplayName "Location" `
--DisplayNamePlural "Locations" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Create a new activity table:
dotnet new pp-entity `
--output "src/Solutions.DataModel" `
--EntityType "Activity" `
--Behavior "New" `
--PublisherPrefix "tom" `
--LogicalName "shiftevent" `
--LogicalNamePlural "shiftevents" `
--DisplayName "Shift Event" `
--DisplayNamePlural "Shift Events" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Add an existing custom table to a solution:
dotnet new pp-entity `
--output "src/Solutions.UI" `
--Behavior "Existing" `
--PublisherPrefix "tom" `
--LogicalName "shiftevent" `
--DisplayName "Shift Event" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Add an existing system table to a solution:
dotnet new pp-entity `
--output "src/Solutions.UI" `
--Behavior "Existing" `
--IsSystemEntity "true" `
--LogicalName "account" `
--DisplayName "Account" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Columns
Add a whole number column to table:
dotnet new pp-entity-attribute `
--output "src/Solutions.DataModel" `
--EntitySchemaName "tom_warehouseitem" `
--AttributeType "WholeNumber" `
--RequiredLevel "required" `
--PublisherPrefix "tom" `
--LogicalName "availablequantity" `
--DisplayName "Available Quantity" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Add a lookup column to table:
dotnet new pp-entity-attribute `
--output "src/Solutions.DataModel" `
--EntitySchemaName "tom_warehousetransaction" `
--AttributeType "Lookup" `
--RequiredLevel "required" `
--LogicalName "tom_itemid" `
--DisplayName "Item" `
--ReferencedEntityName "tom_warehouseitem" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Create a global OptionSet:
dotnet new pp-optionset-global `
--output "src/Solutions.DataModel" `
--RequiredLevel "required" `
--LogicalName "${publisherPrefix}_paymentmethod" `
--DisplayName "Payment Method" `
--SolutionRootPath "Declarations" `
--OptionSetOptions "Visa,Mastercard,Cash" `
--allow-scripts yes
Add global OptionSet to the table:
```console
dotnet new pp-entity-attribute `
--output "src/Solutions.DataModel" `
--EntitySchemaName "${publisherPrefix}_warehousetransaction" `
--AttributeType "OptionSet(Global)" `
--RequiredLevel "required" `
--LogicalName "${publisherPrefix}_paymentmethod" `
--DisplayName "Payment Method" `
--GlobalOptionSetType "Existing" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Create a local OptionSet:
```console
dotnet new pp-entity-attribute `
--output "src/Solutions.DataModel" `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--AttributeType "OptionSet(Local)" `
--RequiredLevel "required" `
--LogicalName "${publisherPrefix}_packagetype" `
--DisplayName "Package Type" `
--OptionSetOptions "Box,Bag,Envelope" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
UI
Create a model-driven app:
dotnet new pp-app-model `
--output "src/Solutions.UI" `
--PublisherPrefix "tom" `
--LogicalName "warehouseapp" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Add a table to a model-driven app component:
dotnet new pp-app-model-component `
--output "src/Solutions.UI" `
--EntityLogicalName "tom_warehouseitem" `
--SolutionRootPath "Declarations" `
--AppName "tom_warehouseapp" `,
--allow-scripts yes
Add an area to the sitemap:
dotnet new pp-sitemap-area `
--output "src/Solutions.UI" `
--SolutionRootPath "Declarations" `
--AppName "tom_warehouseapp" `,
--allow-scripts yes
Add an group to the area:
dotnet new pp-sitemap-group `
--output "src/Solutions.UI" `
--SolutionRootPath "Declarations" `
--AppName "tom_warehouseapp" `,
--allow-scripts yes
Add an subarea into the group:
dotnet new pp-sitemap-subarea `
--output "src/Solutions.UI" `
--SolutionRootPath "Declarations" `
--EntityLogicalName "tom_warehouseitem" `
--AppName "tom_warehouseapp" `,
--allow-scripts yes
Create a main form for a table:
dotnet new pp-entity-form `
--output "src/Solutions.UI" `
--FormType "main" `
--SolutionRootPath "Declarations" `
--EntitySchemaName "tom_warehouseitem" `
--allow-scripts yes
Form design
Form Structure Hierarchy:
┌──────────────────────────────────────────────────────────┐
│ Form │
│ ├─ Tab │
│ ├─ Column │
│ ├─ Section │
│ ├─ Row │
│ ├─ Cell │
│ └─ Control │
└──────────────────────────────────────────────────────────┘
Create a new tab in the form:
dotnet new pp-form-tab `
--output "src/Solutions.UI" `
--FormType "main" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SolutionRootPath "Declarations" `
--RemoveDefaultTab "True" `
--allow-scripts yes
Create a new column in the specific tab:
dotnet new pp-form-column `
--output "src/Solutions.UI" `
--FormType "main" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SolutionRootPath "Declarations" `
--SetToTabFooter "False" `
--TabIndex 1 `
--ColumnWidth "75"
--allow-scripts yes
Create a new section in the specific column:
dotnet new pp-form-section `
--output "src/Solutions.UI" `
--FormType "main" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SetToTabFooter "False" `
--TabIndex 1 `
--ColumnIndex 1 `
--SectionName "GENERAL"
--SolutionRootPath "Declarations" `
--allow-scripts yes
Create a new row in the specific section:
dotnet new pp-form-row `
--output "src/Solutions.UI" `
--FormType "main" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SolutionRootPath "Declarations" `
--SetToTabFooter "False" `
--TabIndex 1 `
--ColumnIndex 1 `
--SectionIndex 1 `
--allow-scripts yes
Create a new cell in the specific row:
dotnet new pp-form-cell `
--output "src/Solutions.UI" `
--RowIndex "1" `
--SetToTabFooter "False" `
--TabIndex 1 `
--ColumnIndex 1 `
--SectionIndex 1 `
--FormType "main" `
--DisplayName "Name" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Create a new control in the specific cell:
dotnet new pp-form-cell-control `
--output "src/Solutions.UI" `
--AttributeType "Text" `
--RowIndex "1" `
--SetToTabFooter "False" `
--TabIndex 1 `
--ColumnIndex 1 `
--SectionIndex 1
--AttributeLogicalName "${publisherPrefix}_name" `
--FormType "main" `
--FormId $warehouseitemFormGuid `
--EntitySchemaName "${publisherPrefix}_warehouseitem" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Security roles
Create a security role:
dotnet new pp-security-role `
--output "src/Solutions.Security" `
--SolutionRootPath "Declarations" `
--rolename "Warehouse Manager" `
--allow-scripts yes
Add privileges to a security role:
dotnet new pp-security-role-privilege `
--output "src/Solutions.Security" `
--SolutionRootPath "Declarations" `
--EntitySchemaName "tom_warehouseitem" `
--rolename "Warehouse Manager" `
--PrivilegeTypeAndLevel "[{ PrivilegeType: Read, Level: Global }, { PrivilegeType: Write, Level: Global }]" `
--allow-scripts yes
Plugins
Initialize a new plugin:
dotnet new pp-plugin `
--output "src/Plugins.Warehouse" `
--PublisherName "tomas" `
--SigningKeyFilePath "PluginKey.snk" `
--Company "NETWORG" `
--allow-scripts yes
Add new assembly:
dotnet new pp-plugin-assembly-step `
--output "src/Solutions.Logic" `
--PluginProjectRootPath "..\\Plugins.Warehouse" `
--SolutionRootPath "Declarations" `
--allow-scripts yes
Add new step to the assembly:
dotnet new pp-plugin-assembly-step `
--output "src/Solutions.Logic" `
--PrimaryEntity "tom_warehousetransaction" `
--PluginProjectName "Plugins.Warehouse" `
--PluginName "ValidateWarehouseTransactionPlugin" `
--Stage "Pre-validation" `
--SdkMessage "Create" `
--SolutionRootPath "Declarations" `
--FilteringAttributes "{tom_itemid, tom_quantity}" `
--AssemblyId "GUID to identifying your assembly" `
--allow-scripts yes
You can add component schema validation to your build process using Power Platform MSBuild targets.
Tools
Templates Builder
The Templates Builder is a utility tool that helps you create custom .NET templates specifically for TALXIS custom controls. This tool reads a ControlManifest.Input.xml file and generates the necessary template files and configuration needed for a .NET template.
How it works
The Templates Builder reads a ControlManifest.Input.xml file (which contains the custom control definition) and generates the necessary template files and configuration needed for a .NET template. This allows you to:
- Convert existing custom controls into reusable templates
- Standardize custom control creation across your organization
- Automate the scaffolding of custom control structures
- Maintain consistency in custom control naming and structure
Usage
./TALXIS.DevKit.Templates.Builder.exe
--PathToTheImputXmlFile "ControlManifest.Input.xml" `
--ResultFolderPath "C:\result" `
--TemplateName "New Custom Control Template" `
--TemplateIdentity "New.Custom.Control.Template" `
--TemplateShortName "pp-control-custom-template"
Parameters
--PathToTheImputXmlFile<span style="color: #ff6b6b; font-weight: bold;">[Required]</span>: Path to theControlManifest.Input.xmlfile containing the custom control definition--ResultFolderPath: Directory where the generated template files will be created--TemplateName: Display name for the new template--TemplateIdentity: Unique identifier for the template (used in template.json)--TemplateShortName: Short name used when invoking the template withdotnet new
Power Platform: Script Library template
A .NET project template for building Dataverse script libraries with TypeScript. It scaffolds a net462 class library project that executes an npm/TypeScript build during MSBuild and outputs a single AMD bundle for use as a web resource.
What you get
- A .NET SDK project targeting
net462 - TypeScript workspace under
TS/with:tsconfig.jsonconfigured to emit a single bundle toTS/build/<LibraryName>.jspackage.jsonwithtypescriptand@types/xrm- npm scripts:
buildandstart(watch)
- MSBuild target that runs
npm installandnpm run buildautomatically onBuild
Prerequisites
- .NET SDK 6+ (
dotnet --version) - Node.js and npm (
node -v,npm -v)
Create a new project
dotnet new pp-script-library -n UI.Scripts --LibraryName MyCompany.Scripts
Build and develop
- Build with MSBuild (this will run npm automatically):
dotnet build - Develop with watch mode (run inside
TS/):
Then build the .NET project (optional) to copy outputs to the project output directory.npm install npm run start
Outputs
After building, you will find:
TS/build/<LibraryName>.jsTS/build/<LibraryName>.js.mapTS/build/<LibraryName>.d.ts
Use in Dataverse
- Upload
TS/build/<LibraryName>.jsas a Script (JavaScript) Web Resource.
Troubleshooting
- If
npmis not found duringdotnet build, ensure Node.js is installed and on PATH. - To force a clean TypeScript build:
cd TS rm -rf node_modules build npm install npm run build - If watch mode does not re-emit, verify
tsconfig.jsonpaths and that files are saved.
Power Platform: Script Test Template
This template creates a test project for Power Platform JavaScript/TypeScript web resources using Jest. It provides a complete testing infrastructure with Xrm API mocks, helper functions, and integration with .NET test framework.
Overview
The pp-test-script template generates a test project configured for testing Dataverse web resources (form scripts, ribbon commands, etc.). It includes:
- Jest test framework with jsdom environment
- Xrm API mocks for Dataverse client-side API
- Helper functions for creating test objects (forms, attributes, controls)
- Web resource loader utility for testing your scripts
- .NET project integration for running tests via
dotnet test - Automatic npm package installation
Basic Usage
Create a script test project:
dotnet new pp-test-script `
--output "tests/Script.Tests" `
--ScriptTestProjectName "Script.Tests" `
--ScriptLibraryPath "../src/Scripts.Warehouse" `
--allow-scripts yes
The template creates:
- .NET Test Project - A .NET 8.0 project confiured to run Jest tests via
dotnet test - Jest Confiuration -
jest.config.jsconfigured for jsdom environment - Packae Configuration -
package.jsonwith Jest dependencies - jest-core Directory - Reusable core library containing:
- Xrm API mocks (
setupXrm.js) - Helper functions (
helpers.js) - Main export (
index.js)
- Xrm API mocks (
- Tests Directory - Sample test structure with utilities
- Web Resource Loader - Utility for loading and testing web resources
Project Structure
Script.Tests/
├── jest-core/
│ ├── index.js # Main export for jest-core
│ ├── setupXrm.js # Xrm API mock setup
│ ├── helpers.js # Helper functions for test objects
│ └── package.json # jest-core package definition
├── tests/
│ └── utils/
│ └── loadWebRes.js # Web resource loader utility
├── jest.config.js # Jest configuration
├── package.json # Project npm dependencies
└── Script.Tests.csproj # .NET project file
Basic Test Example
Create a test file in the tests directory (e.g., tests/myScript.test.js):
const { setupXrm, resetXrmMocks, makeForm, makeAttr, makeControl } = require('../jest-core');
const { loadWebResource } = require('./utils/loadWebRes');
describe('My Form Script', () => {
beforeEach(() => {
setupXrm();
});
afterEach(() => {
resetXrmMocks();
});
test('should set field value on form load', () => {
// Arrange
const nameAttr = makeAttr('');
const nameControl = makeControl();
const formContext = makeForm(
{ name: nameAttr },
{ name: nameControl }
);
// Load your web resource
const webRes = loadWebResource('path/to/your/script.js');
// Act - Call your function
webRes.onFormLoad(formContext);
// Assert
expect(nameAttr.setValue).toHaveBeenCalledWith('Default Value');
});
});
Power Platform: Plugin Test Template
- FakeXrmEasy v2 documentation:
https://dynamicsvalue.github.io/fake-xrm-easy-docs/
What's included
FakeXrmEasyTestBase.cs: a base class that:- creates an
IXrmFakedContextviaMiddlewareBuilder(.AddCrud(),.UseCrud(),.UseMessages()); - sets the license via
SetLicense(...)(default isCommercial); - provides an
IOrganizationServicevia_context.GetOrganizationService().
- creates an
How to use FakeXrmEasyTestBase.cs
Inherit from the base class and use _context to seed data and _service to invoke the Organization Service.
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Xrm.Sdk;
namespace Plugins.Tests
{
[TestClass]
public class AccountPluginTests : FakeXrmEasyTestBase
{
[TestMethod]
public void Creates_account_successfully()
{
// Arrange: seed in-memory data
var account = new Entity("account")
{
Id = Guid.NewGuid(),
["name"] = "Test Account"
};
_context.Initialize(new List<Entity> { account });
// Act: use IOrganizationService from the base
var createdId = _service.Create(new Entity("contact"));
// Assert: verify with context storage
var created = _context.Data["contact"][createdId];
Assert.IsNotNull(created);
}
}
}
Important notes and dependencies
- FakeXrmEasy license dependency: calling
SetLicense(...)is required before.Build(). If needed, replaceCommercialwithRPL_1_5orNonCommercialaccording to your usage terms. - Message executors dependency: if you need custom message executors, uncomment in the base class
.AddFakeMessageExecutors(typeof(FakeXrmEasyTestBase).Assembly)before.UseMessages().- Dependency: custom executors become available only after their assembly is added.
- Activation:
.UseMessages()enables the message pipeline.
Collaboration
We are happy to collaborate with developers and contributors interested in enhancing Power Platform development processes. If you have feedback, suggestions, or would like to contribute, please feel free to submit issues or pull requests.
Local building and debugging
Using your local version of templates
Use the provided VS Code task to build the project and update the local templates:
- Open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P)
- Search for "Tasks: Run Task" and select it
- Choose "Update local templates" from the list
Contact us
For further information or to discuss potential use cases for your team, please reach out to us at hello@networg.com.
-
net8.0
- No dependencies.
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.21.0 | 47 | 5/14/2026 |
| 1.20.0 | 44 | 5/14/2026 |
| 1.19.2 | 114 | 5/4/2026 |
| 1.19.1 | 97 | 5/4/2026 |
| 1.19.0 | 99 | 5/4/2026 |
| 1.18.0 | 108 | 5/1/2026 |
| 1.17.0 | 104 | 4/29/2026 |
| 1.16.0 | 106 | 4/28/2026 |
| 1.15.0 | 96 | 4/28/2026 |
| 1.14.0 | 105 | 4/28/2026 |
| 1.13.0 | 107 | 4/28/2026 |
| 1.12.0 | 113 | 4/27/2026 |
| 1.11.0 | 513 | 8/14/2025 |
| 1.10.0 | 524 | 8/6/2025 |
| 1.9.0 | 503 | 8/6/2025 |
| 1.8.0 | 556 | 8/2/2025 |
| 1.6.0 | 456 | 5/27/2025 |
| 1.5.0 | 433 | 3/22/2025 |
| 1.4.0 | 371 | 3/22/2025 |