DynamicsCrm.DevKit.Analyzers 4.0.0

dotnet add package DynamicsCrm.DevKit.Analyzers --version 4.0.0
                    
NuGet\Install-Package DynamicsCrm.DevKit.Analyzers -Version 4.0.0
                    
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="DynamicsCrm.DevKit.Analyzers" Version="4.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DynamicsCrm.DevKit.Analyzers" Version="4.0.0" />
                    
Directory.Packages.props
<PackageReference Include="DynamicsCrm.DevKit.Analyzers" />
                    
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 DynamicsCrm.DevKit.Analyzers --version 4.0.0
                    
#r "nuget: DynamicsCrm.DevKit.Analyzers, 4.0.0"
                    
#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 DynamicsCrm.DevKit.Analyzers@4.0.0
                    
#: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=DynamicsCrm.DevKit.Analyzers&version=4.0.0
                    
Install as a Cake Addin
#tool nuget:?package=DynamicsCrm.DevKit.Analyzers&version=4.0.0
                    
Install as a Cake Tool
  ____                              _           ____                  ____             _  ___ _        _                _                        
 |  _ \ _   _ _ __   __ _ _ __ ___ (_) ___ ___ / ___|_ __ _ __ ___   |  _ \  _____   _| |/ (_) |_     / \   _ __   __ _| |_   _ _______ _ __ ___ 
 | | | | | | | '_ \ / _` | '_ ` _ \| |/ __/ __| |   | '__| '_ ` _ \  | | | |/ _ \ \ / / ' /| | __|   / _ \ | '_ \ / _` | | | | |_  / _ \ '__/ __|
 | |_| | |_| | | | | (_| | | | | | | | (__\__ \ |___| |  | | | | | |_| |_| |  __/\ V /| . \| | |_ _ / ___ \| | | | (_| | | |_| |/ /  __/ |  \__ \
 |____/ \__, |_| |_|\__,_|_| |_| |_|_|\___|___/\____|_|  |_| |_| |_(_)____/ \___| \_/ |_|\_\_|\__(_)_/   \_\_| |_|\__,_|_|\__, /___\___|_|  |___/
        |___/                         https://github.com/phuocle/Dynamics-Crm-DevKit 4.00.00.00 Build: 31.12.2025 23:59:59|___/                                   

🔍 DynamicsCrm.DevKit.Analyzers

A Roslyn-based code analyzer package for Microsoft Dynamics 365 / Power Platform development. It provides compile-time diagnostics to help developers follow best practices and avoid common pitfalls when building plugins, custom workflows, and other CRM customizations.

đŸ“Ļ Installation

Install via NuGet:

dotnet add package DynamicsCrm.DevKit.Analyzers

Or add to your .csproj:

<PackageReference Include="DynamicsCrm.DevKit.Analyzers" Version="*" PrivateAssets="all" />

📋 Diagnostic Rules

Rule ID Severity Description
DEVKIT1001 Error Create/Update message should have filtering attributes
DEVKIT1002 Warning Don't use ColumnSet(true)
DEVKIT1003 Error Plugin image validation
DEVKIT1004 Info Use of deprecated SDK messages
DEVKIT1005 Warning EntityReference maybe null
DEVKIT1006 Warning Don't use batch request types in plug-ins
DEVKIT1007 Error IPlugin implementations should be stateless
DEVKIT1008 Error Don't use parallel execution in plug-ins
DEVKIT1009 Warning Set KeepAlive to false for external HTTP calls
DEVKIT1010 Warning Set Timeout for external HTTP calls
DEVKIT1011 Warning Use InvalidPluginExecutionException for errors
DEVKIT1012 Info Consider using ITracingService in plug-ins
DEVKIT1013 Info Avoid registering plugins on Retrieve/RetrieveMultiple
DEVKIT1014 Error Avoid AppDomain event registration in plug-ins
DEVKIT1015 Info Avoid blocking async patterns in plug-ins
DEVKIT1016 Info Avoid retrieving unpublished metadata
DEVKIT1017 Info Avoid Console output in plug-ins
DEVKIT1018 Error Avoid File/IO operations in plug-ins
DEVKIT1019 Warning Consider checking context.Depth to prevent infinite loops
DEVKIT1020 Error DataProvider must have DataSource

❌ DEVKIT1001

Create/Update message should have filtering attributes

Severity: Error

MS Best Practice: 📚 Include filtering attributes with plug-in registration

This analyzer ensures that plugin registrations for Create, CreateMultiple, Update, UpdateMultiple, OnExternalCreated, or OnExternalUpdated messages include specific filtering attributes. This prevents the plugin from executing on every field change, which can significantly impact performance.

Bad Code:

// ❌ Empty filtering attributes
[CrmPluginRegistration("Create", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous, 
    filteringAttributes: "",
    stepName: "Pre-Create Account")]

// ❌ All attributes
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous, 
    filteringAttributes: "*", 
    stepName: "Pre-Update Account")]

Good Code:

// ✅ Specific attributes
[CrmPluginRegistration("Create", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous, 
    filteringAttributes: "name,accountnumber",
    stepName: "Post-Create Account")]
// ✅ Specific attributes
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous, 
    filteringAttributes: "name,accountnumber",
    stepName: "Pre-Update Account")]

📖 Documentation


âš ī¸ DEVKIT1002

Don't use ColumnSet(true)

Severity: Warning

MS Best Practice: Retrieve specific columns for a table via query APIs

Warns against using ColumnSet(true) which retrieves all columns from an entity. This is a performance anti-pattern as it retrieves unnecessary data.

Bad Code:

// ❌ Retrieves all columns
var entity = service.Retrieve("account", id, new ColumnSet(true));

// ❌ AllColumns = true
var query = new QueryExpression("account")
{
    ColumnSet = new ColumnSet { AllColumns = true }
};

// ❌ FetchXML with all-attributes
var fetch = @"<fetch><entity name='account'><all-attributes/></entity></fetch>";

Good Code:

// ✅ Only retrieve needed columns
var entity = service.Retrieve("account", id, new ColumnSet("name", "accountnumber"));

📖 Documentation


❌ DEVKIT1003

Plugin image validation

Severity: Error

MS Best Practice: Understand the execution context (Plugin Images)

Validates that plugin image configurations are compatible with the message and stage. The Dynamics 365 platform has specific rules about when Pre-Images and Post-Images are available:

Message Stage Pre-Image Post-Image
Create Pre-Validation ❌ ❌
Create Pre-Operation ❌ ❌
Create Post-Operation ❌ ✅
Update Pre-Validation ✅ ❌
Update Pre-Operation ✅ ❌
Update Post-Operation ✅ ✅
Delete Pre-Validation ✅ ❌
Delete Pre-Operation ✅ ❌
Delete Post-Operation ✅ ❌

Bad Code:

// ❌ Pre-Create cannot have Pre-Image or Post-Image
[CrmPluginRegistration("Create", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
    Image1Type = ImageTypeEnum.PreImage, Image1Attributes = "name")]

// ❌ Pre-Update cannot have Post-Image  
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, ExecutionModeEnum.Synchronous,
    Image1Type = ImageTypeEnum.PostImage, Image1Attributes = "name")]

Good Code:

// ✅ Post-Create can have Post-Image
[CrmPluginRegistration("Create", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
    Image1Type = ImageTypeEnum.PostImage, Image1Attributes = "name")]

// ✅ Post-Update can have both images
[CrmPluginRegistration("Update", "account", StageEnum.PostOperation, ExecutionModeEnum.Synchronous,
    Image1Type = ImageTypeEnum.PreImage, Image1Attributes = "name",
    Image2Type = ImageTypeEnum.PostImage, Image2Attributes = "name")]

📖 Documentation


â„šī¸ DEVKIT1004

Use of deprecated SDK messages

Severity: Warning

MS Best Practice: Deprecated SDK messages

Warns when using deprecated request/response classes from Microsoft.Crm.Sdk.Messages. These messages may be removed in future SDK versions.

Deprecated Messages Include:

  • AddProductToKitRequest/Response
  • AddSubstituteProductRequest/Response
  • AssociateEntitiesRequest/Response
  • CompoundCreateRequest/Response
  • CompoundUpdateRequest/Response
  • ConvertKitToProductRequest/Response
  • ConvertProductToKitRequest/Response
  • DisassociateEntitiesRequest/Response
  • ExecuteFetchRequest/Response
  • SetStateRequest/Response
  • And more...

Bad Code:

// ❌ Deprecated message
var request = new SetStateRequest
{
    EntityMoniker = new EntityReference("account", accountId),
    State = new OptionSetValue(1),
    Status = new OptionSetValue(2)
};
service.Execute(request);

Good Code:

// ✅ Use Update instead
var account = new Entity("account", accountId)
{
    ["statecode"] = new OptionSetValue(1),
    ["statuscode"] = new OptionSetValue(2)
};
service.Update(account);

📖 Documentation


âš ī¸ DEVKIT1005

EntityReference maybe null

Severity: Error

MS Best Practice: Null safety pattern for lookup fields

Flags potential null reference exceptions when accessing Id, Name, or LogicalName properties of an EntityReference that may be null. Lookup fields in Dynamics 365 can return null if no value is set.

Bad Code:

// ❌ EntityReference may be null
var ownerId = entity.GetAttributeValue<EntityReference>("ownerid").Id;
var ownerName = entity.GetAttributeValue<EntityReference>("ownerid").Name;

// ❌ In string concatenation
var message = "Owner: " + entity.GetAttributeValue<EntityReference>("ownerid").Name;

Good Code:

// ✅ Null-conditional operator
var ownerId = entity.GetAttributeValue<EntityReference>("ownerid")?.Id;
var ownerName = entity.GetAttributeValue<EntityReference>("ownerid")?.Name;

// ✅ Null check first
var ownerRef = entity.GetAttributeValue<EntityReference>("ownerid");
if (ownerRef != null)
{
    var ownerId = ownerRef.Id;
}

📖 Documentation


âš ī¸ DEVKIT1006

Don't use batch request types in plug-ins and workflow activities

Severity: Warning

MS Best Practice: Don't use batch request types in plug-ins

Warns against using batch request types (ExecuteMultipleRequest, ExecuteTransactionRequest, CreateMultipleRequest, UpdateMultipleRequest, UpsertMultipleRequest) within plug-ins or workflow activities. These can cause performance issues and timeout errors.

Bad Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // ❌ Using ExecuteMultipleRequest in plugin
        var batch = new ExecuteMultipleRequest();
        foreach (var entity in entities)
        {
            batch.Requests.Add(new UpdateRequest { Target = entity });
        }
        service.Execute(batch);
    }
}

Good Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // ✅ Execute each request individually
        foreach (var entity in entities)
        {
            service.Update(entity);
        }
    }
}

📖 Documentation


❌ DEVKIT1007

IPlugin implementations should be stateless

Severity: Error

Detects assignments to instance fields or properties during plug-in execution. IPlugin classes are cached and reused across multiple threads - storing state in instance members can cause thread-safety issues and data inconsistencies.

MS Best Practice: Develop IPlugin implementations as stateless

Bad Code:

public class MyPlugin : IPlugin
{
    // ❌ Mutable instance field
    private IOrganizationService _service;
    private IPluginExecutionContext _context;
    
    public void Execute(IServiceProvider serviceProvider)
    {
        // ❌ Assigning to instance field during execution
        _context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        _service = factory.CreateOrganizationService(_context.UserId);
    }
}

Good Code:

public class MyPlugin : IPlugin
{
    // ✅ Readonly field assigned in constructor (for configuration)
    private readonly string _secureConfig;
    
    public MyPlugin(string unsecure, string secure)
    {
        _secureConfig = secure;
    }
    
    public void Execute(IServiceProvider serviceProvider)
    {
        // ✅ Local variables instead of instance fields
        var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        var service = factory.CreateOrganizationService(context.UserId);
    }
}

📖 Documentation


❌ DEVKIT1008

Don't use parallel execution in plug-ins and workflow activities

Severity: Error

MS Best Practice: Do not use parallel execution within plug-ins and workflow activities

Detects usage of parallel execution patterns within IPlugin or CodeActivity classes. Multi-threading and parallel execution are not supported in the Dataverse sandbox and can cause unpredictable behavior.

Detected Patterns:

  • Task.Run(), Task.Factory.StartNew()
  • Parallel.For(), Parallel.ForEach(), Parallel.Invoke()
  • new Thread()
  • ThreadPool.QueueUserWorkItem()

Bad Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var entities = GetEntities();
        
        // ❌ Using Parallel.ForEach
        Parallel.ForEach(entities, entity => {
            service.Update(entity);
        });
        
        // ❌ Using Task.Run
        Task.Run(() => DoSomething());
        
        // ❌ Using Thread
        var thread = new Thread(() => DoWork());
        thread.Start();
    }
}

Good Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var entities = GetEntities();
        
        // ✅ Sequential processing
        foreach (var entity in entities)
        {
            service.Update(entity);
        }
        
        // ✅ Direct method call
        DoSomething();
    }
}

📖 Documentation


âš ī¸ DEVKIT1009

Set KeepAlive to false for external HTTP calls

Severity: Warning

MS Best Practice: Set KeepAlive to false when interacting with external hosts

Warns when using HttpClient or WebRequest in plugins without setting KeepAlive to false. The sandbox environment has connection pool limitations that can cause issues when KeepAlive is enabled.

Bad Code:

// ❌ HttpClient with default KeepAlive (true)
using (var client = new HttpClient())
{
    var response = client.GetAsync(url).GetAwaiter().GetResult();
}

Good Code:

// ✅ HttpClient with ConnectionClose = true
using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.ConnectionClose = true;
    var response = client.GetAsync(url).GetAwaiter().GetResult();
}

📖 Documentation


âš ī¸ DEVKIT1010

Set Timeout for external HTTP calls

Severity: Warning

MS Best Practice: Set Timeout when making external calls from a plug-in

Warns when using HttpClient in plugins without setting an explicit Timeout. The default HttpClient timeout is 100 seconds, which may exceed the plugin timeout limit.

Bad Code:

// ❌ HttpClient with default timeout (100 seconds)
using (var client = new HttpClient())
{
    var response = client.GetAsync(url).GetAwaiter().GetResult();
}

Good Code:

// ✅ HttpClient with explicit timeout
using (var client = new HttpClient())
{
    client.Timeout = TimeSpan.FromSeconds(15);
    var response = client.GetAsync(url).GetAwaiter().GetResult();
}

📖 Documentation


âš ī¸ DEVKIT1013

Avoid registering plugins on Retrieve/RetrieveMultiple

Severity: Warning

MS Best Practice: Limit the registration of plug-ins for Retrieve and RetrieveMultiple messages

Warns when a plugin is registered on Retrieve or RetrieveMultiple messages. These messages are called very frequently and can significantly impact system performance.

Bad Code:

// ❌ Plugin on RetrieveMultiple - runs EVERY time a view is loaded
[CrmPluginRegistration("RetrieveMultiple", "account", StageEnum.PostOperation, 
    ExecutionModeEnum.Synchronous, "", "RetrieveMultiple Account")]
public class RetrieveMultipleAccountPlugin : IPlugin { }

Good Code:

// ✅ Use Create/Update to pre-calculate values instead
[CrmPluginRegistration("Update", "account", StageEnum.PreOperation, 
    ExecutionModeEnum.Synchronous, "revenue", "Calculate Account Rating")]
public class CalculateAccountRatingPlugin : IPlugin { }

📖 Documentation


âš ī¸ DEVKIT1011

Use InvalidPluginExecutionException for errors

Severity: Warning

MS Best Practice: Use InvalidPluginExecutionException in plug-ins and workflow activities

Warns when throwing exceptions other than InvalidPluginExecutionException in plugins. Only this exception type is properly handled by the platform and shows messages to users.

Bad Code:

// ❌ Generic Exception - user sees "An error occurred"
throw new Exception("Something went wrong");

Good Code:

// ✅ InvalidPluginExecutionException - message shown to user
throw new InvalidPluginExecutionException("Please provide a valid account name.");

📖 Documentation


â„šī¸ DEVKIT1012

Consider using ITracingService in plug-ins

Severity: Warning

MS Best Practice: Use ITracingService in Plug-ins

Recommends using ITracingService in plug-in classes for debugging and monitoring.

Bad Code:

// âš ī¸ No tracing - difficult to debug
public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider) { }
}

Good Code:

// ✅ Uses tracing for debugging
public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var tracingService = (ITracingService)serviceProvider
            .GetService(typeof(ITracingService));
        tracingService.Trace("Plugin started");
    }
}

📖 Documentation


âš ī¸ DEVKIT1016

Avoid retrieving unpublished metadata

Severity: Warning

MS Best Practice: Retrieve published metadata

Detects RetrieveAsIfPublished = true on metadata requests. Retrieving unpublished metadata causes slower performance.

Bad Code:

// âš ī¸ RetrieveAsIfPublished = true causes performance issues
var request = new RetrieveEntityRequest
{
    MetadataId = entityId,
    RetrieveAsIfPublished = true
};

Good Code:

// ✅ Default behavior retrieves published metadata only
var request = new RetrieveEntityRequest
{
    MetadataId = entityId
};

📖 Documentation


❌ DEVKIT1014

Avoid AppDomain event registration in plug-ins

Severity: Error

Detects subscription to AppDomain events in plugins. Plugin instances are cached and reused, so subscribing to AppDomain events can cause memory leaks.

Bad Code:

// ❌ Memory leak - event handler never removed
AppDomain.CurrentDomain.UnhandledException += (s, e) => { };

Good Code:

// ✅ Use try-catch for exception handling
try { /* work */ }
catch (Exception ex) { throw new InvalidPluginExecutionException("Error", ex); }

📖 Documentation


âš ī¸ DEVKIT1015

Avoid blocking async patterns in plug-ins

Severity: Warning

Detects usage of GetAwaiter().GetResult(), .Result, and .Wait() on Tasks in plugins. These can cause deadlocks.

Patterns Detected:

// âš ī¸ Can cause deadlocks
task.GetAwaiter().GetResult();
task.Result;
task.Wait();

Better Alternative:

// ✅ Use ConfigureAwait(false) or synchronous APIs
var result = task.ConfigureAwait(false).GetAwaiter().GetResult();

📖 Documentation


â„šī¸ DEVKIT1017

Avoid Console output in plug-ins and workflow activities

Severity: Info

Console output methods like Console.Write() and Console.WriteLine() have no effect in the Dataverse sandbox environment. The console stream is redirected to null.

Patterns Detected:

// âš ī¸ Has no effect in sandbox
Console.WriteLine("Debug message");
Console.Write($"Processing: {entity.Id}");
Console.Error.WriteLine("Error occurred");

Better Alternative:

// ✅ Use ITracingService for logging
var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace("Debug message");
tracingService.Trace($"Processing: {entity.Id}");

📖 Documentation


❌ DEVKIT1018

Avoid File/IO operations in plug-ins and workflow activities

Severity: Error

System.IO file operations are blocked in the Dataverse sandbox environment and will throw SecurityException at runtime.

Bad Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // ❌ File.ReadAllText - blocked in sandbox
        var content = File.ReadAllText("config.txt");
        
        // ❌ File.WriteAllText - blocked in sandbox
        File.WriteAllText("log.txt", "Plugin executed");
        
        // ❌ new FileStream - blocked in sandbox
        using (var stream = new FileStream("data.bin", FileMode.Open))
        {
        }
        
        // ❌ new StreamReader - blocked in sandbox
        using (var reader = new StreamReader("input.txt"))
        {
        }
    }
}

Good Code:

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // ✅ Use Dataverse storage instead of files
        var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
        tracingService.Trace("Use tracing instead of file logging");
        
        // ✅ Store data using Note attachments
        var note = new Entity("annotation")
        {
            ["subject"] = "Plugin Output",
            ["notetext"] = "Data to store"
        };
        service.Create(note);
    }
}

📖 Documentation


âš ī¸ DEVKIT1019

Consider checking context.Depth to prevent infinite loops

Severity: Warning

This analyzer recommends checking IPluginExecutionContext.Depth in plugin classes to prevent infinite loops when plugins modify entities that trigger themselves recursively.

Bad Code:

public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // ❌ No depth check - can cause infinite loop
        var context = (IPluginExecutionContext)serviceProvider
            .GetService(typeof(IPluginExecutionContext));
        var target = (Entity)context.InputParameters["Target"];
        
        // This update triggers the plugin again!
        var update = new Entity("account", target.Id);
        update["modifiedon"] = DateTime.UtcNow;
        service.Update(update);
    }
}

Good Code:

public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = (IPluginExecutionContext)serviceProvider
            .GetService(typeof(IPluginExecutionContext));
        
        // ✅ Exit early if this is a recursive call
        if (context.Depth > 1) return;
        
        var target = (Entity)context.InputParameters["Target"];
        
        // Now safe to update
        var update = new Entity("account", target.Id);
        update["modifiedon"] = DateTime.UtcNow;
        service.Update(update);
    }
}

📖 Documentation


❌ DEVKIT1020

DataProvider must have DataSource

Severity: Error

MS Best Practice: Virtual Table Data Providers

This analyzer detects when a CrmPluginRegistration attribute uses PluginType.DataProvider but the DataSource parameter is empty or missing. DataProvider plugins require a valid DataSource to function correctly at runtime.

Bad Code:

public class MyPlugin : IPlugin
{
    // ❌ DataSource is empty - will fail at runtime
    [CrmPluginRegistration("Dev.DevKit.Server.DataProviders.Cds.Retrieve", "Retrieve", 
        PluginType.DataProvider, DataSource = "")]
    public void Execute(IServiceProvider serviceProvider) { }
}

Good Code:

public class MyPlugin : IPlugin
{
    // ✅ DataSource is specified with valid data source name
    [CrmPluginRegistration("Dev.DevKit.Server.DataProviders.Cds.Retrieve", "Retrieve", 
        PluginType.DataProvider, DataSource = "v4_sql_datasource")]
    public void Execute(IServiceProvider serviceProvider) { }
}

📖 Documentation


âš™ī¸ Configuration

You can suppress specific rules in your .editorconfig:

[*.cs]
# Disable specific rules
dotnet_diagnostic.DEVKIT1001.severity = none
dotnet_diagnostic.DEVKIT1002.severity = suggestion

Or use #pragma directives:

#pragma warning disable DEVKIT1002
var entity = service.Retrieve("account", id, new ColumnSet(true));
#pragma warning restore DEVKIT1002

📋 Requirements

  • .NET Standard 2.0 compatible projects
  • Visual Studio 2019+ or any IDE with Roslyn analyzer support

📄 License

This project is part of DynamicsCrm.DevKit.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has 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
4.0.0 113 12/31/2025
3.55.55.55 585 4/3/2025
3.45.67.89 214 3/31/2025
3.44.44.44 614 12/26/2024
3.33.33.34 668 3/28/2024
3.33.33.33 351 12/31/2023
2.13.33 11,878 9/24/2021
2.12.31 6,856 7/7/2021
2.10.31 8,038 10/31/2020
2.2.29 777 3/1/2020
2.1.1 2,100 11/14/2019
2.1.0 909 9/30/2019
2.0.0 870 7/31/2019

Version 4.0.0:
- 20 diagnostic rules covering plugin best practices
- DEVKIT1001-DEVKIT1020 analyzers for common Dynamics 365 pitfalls
- Support for filtering attributes, ColumnSet validation, image validation
- Detection of deprecated SDK messages, parallel execution, and file I/O operations
- Recommendations for ITracingService usage and context.Depth checks