Google Anlatics

Saturday, July 12, 2025

Mastering Microsoft Dynamics 365 CRM Plugins: The Ultimate Deep Dive

Microsoft Dynamics 365 is an incredibly powerful platform, and plugins are one of its best-kept secrets for unlocking real business transformation. If you’ve ever wondered how to enforce complex validation, perform lightning-fast integrations, or inject truly custom business logic at just the right moment — plugins are your answer. After a decade of developing, troubleshooting, and optimising plugins for enterprises and startups alike, here’s a comprehensive guide on everything you need to know, distilled from years in the trenches.

What Exactly is a Dynamics 365 Plugin?

At its core, a Dynamics 365 plugin is a custom .NET class that runs when a specific event happens in the Dataverse platform. Think of plugins as your own logic, running invisibly on the server, responding instantly to changes like creating, updating, or deleting a record. While Microsoft calls these “extensibility points,” I see them as strategic hooks to make the system behave precisely the way your business demands.

Why should you care? Because plugins can do what no other tool in Dynamics can: enforce rules and logic at the data layer, right inside the transaction. This means the rules are always enforced, regardless of whether data is entered through the user interface, an Excel import, or a third-party integration. When built well, plugins are fast, reliable, and can even interact with external systems in real time.

Real-World Plugin Use Cases

  • Advanced Validation: For example, enforcing discount rules or compliance checks that are simply too complex for Business Rules or Power Automate flows.
  • Live Integration: Instantly syncing data to an ERP, or checking an external fraud service before allowing a new lead to save.
  • Automated Decisions: Routing records to the right team, calculating bonuses, or auto-populating related data, all before the user even sees the change.
  • Transactional Consistency: Ensuring that if anything goes wrong, all changes are rolled back together.

Understanding the Plugin Execution Pipeline

Mastering plugins starts with understanding the event pipeline. Here’s how Dynamics 365 processes an operation, and where your code can plug in:

Stages in the Pipeline

  • Pre-Validation: The very first gate, running before security checks and outside the main transaction. Use this for quick early validation.
  • Pre-Operation: Runs just before the record is saved, inside the database transaction. Here, you can change data before it’s committed — great for setting default values or enforcing business logic.
  • Main Operation: This is the core platform event (like actually creating the record). Custom code cannot run here.
  • Post-Operation: Executes after the record is saved but still inside the transaction (if sync), or right after commit (if async). Perfect for tasks like creating related records, sending notifications, or updating other data based on the saved result.

Synchronous vs Asynchronous Plugins

  • Synchronous plugins run in real-time; the user waits for them to finish. These are ideal for validation and actions that must complete before saving.
  • Asynchronous plugins run in the background, after the data is saved. These are great for tasks like calling web services or updating external systems, as they do not impact the user’s experience.

Transaction and Rollback

A crucial point: synchronous plugins in Pre-Operation and Post-Operation are part of a single transaction. If a plugin fails, the entire operation rolls back. Asynchronous plugins, on the other hand, cannot roll back the original data change.

Depth and Preventing Infinite Loops

Plugins can trigger other plugins, and Dynamics tracks this with a Depth property. If your plugin is triggered by another plugin’s update, Depth increases. To avoid infinite loops, always check the Depth and consider returning early if it’s above a certain threshold.

Images: Pre-Image and Post-Image

Plugins can access snapshots of the record before and after the change. Register a Pre-Image to see the original values, or a Post-Image to get final values after save. This is essential for comparing changes.

Filtering Attributes

When registering Update-step plugins, specify the fields that should trigger your logic. This makes your plugin more efficient and prevents unnecessary executions.

Synchronous vs Asynchronous Plugins: When to Use Each

Ask yourself:

  • Do you need to stop the save if something goes wrong? Use synchronous.
  • Is your logic time-consuming or depends on slow external systems? Go with asynchronous.
  • Do you need to provide instant feedback to users? Only synchronous plugins (or real-time workflows) can display error messages instantly.
  • Is it okay if the operation completes and your custom logic happens shortly after? Asynchronous is ideal.

In most enterprise systems, a mix of sync and async plugins keeps things both robust and performant.

Plugins vs. Other Tools

How do plugins compare to Power Automate, Business Rules, and JavaScript?

  • Plugins are best for complex, transactional, or high-performance logic.
  • Power Automate is great for cross-system automation, but it is always asynchronous and cannot cancel a save.
  • Business Rules are quick for simple field logic on forms but don’t work in all scenarios.
  • JavaScript is for UI interactions only, and never runs on imports or integrations.

Writing Your First Plugin: Key Components

The IPlugin Interface

Every plugin implements the IPlugin interface and its Execute(IServiceProvider serviceProvider) method. This is where everything happens.

public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Plugin logic here
}
}

Accessing Context and Services

  • IPluginExecutionContext: Gives you all the event info — what triggered the plugin, which entity, what stage, what data.
  • IOrganizationService: Use this to read or write data in Dataverse.
  • ITracingService: Your best friend for debugging — trace messages appear in Plugin Trace Logs or System Jobs.

Typical plugin setup:

var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);
var tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

Implementing Logic

  • Check that the event is the one you want (e.g. context.MessageName == "Create").
  • Validate or transform data as needed.
  • Perform CRUD operations with IOrganizationService.
  • Trace key steps for diagnostics.

Exception Handling

To cancel a save or surface a user-friendly error, throw an InvalidPluginExecutionException with a message. Always trace exceptions for easier support.

Registering Plugins

Use the Plugin Registration Tool to upload your assembly, then register “steps” to define which event, entity, and stage should trigger your plugin. Include the plugin in your Solution so it can be deployed across environments.

Plugin Best Practices

  • Keep plugins stateless and thread-safe. Never use static variables for data you care about across plugin runs.
  • Early returns. Always check if the context fits your logic — exit early if not.
  • Avoid long-running code in synchronous plugins. Any delay here holds up users.
  • Filter attributes for updates. Register plugins to fire only on fields that matter.
  • Never run batch operations or spawn threads inside plugins. If you need bulk processing, do it outside plugins or break it into smaller operations.
  • Query only what you need. Minimize data retrieval for performance.
  • Avoid updating the same record in Post-Operation. This creates potential loops.
  • Use transactions wisely. Know that a sync plugin failure will roll back all changes.
  • Trace smartly. Use ITracingService.Trace for entry, exit, and exceptions—don’t overdo it in production.
  • Cache carefully. For reference data, use thread-safe, short-lived caches. Never cache large datasets in memory.
  • External API calls. Always set timeouts, handle errors, and do this asynchronously if possible.
  • Use secure config for secrets. Store API keys and sensitive info in Secure Configuration at plugin registration, not in code.
  • Prevent infinite loops. Use Depth checks, or flag attributes if needed.

Advanced Techniques for Senior Developers

  • Custom Actions and APIs: Create your own Dataverse messages with input/output parameters, then use plugins to implement the logic. This is perfect for reusable business operations.
  • Plugin Isolation/Sandbox: All plugins in the cloud run in a secure sandbox with limited permissions, no file system or registry access, and capped memory. Respect these boundaries.
  • Generic plugins: Handle logic for multiple entities in a single class by switching based on the context.
  • Impersonation: You can run plugins as a specific user (for special permissions). Useful for system-level operations.
  • Integration with external systems: Consider webhooks or offloading heavy work to Azure Functions for maximum scalability and minimum user impact.
  • Monitoring: Leverage Plugin Trace Logs and custom telemetry (for example, using Application Insights) to track performance and errors.

Automating Plugin Deployment: spkl and DevOps

Manual plugin registration is error-prone and doesn’t scale. Modern teams use tools like spkl (Sparkle) to automate deployment in CI/CD pipelines. You define registration details in a config file and use spkl to push your assemblies and steps. This keeps everything in source control and repeatable across environments. Microsoft’s Power Platform CLI is another great tool for managing solutions and plugin projects automatically.

Testing and Debugging Plugins

Unit testing plugins is a huge productivity booster. Frameworks like FakeXrmEasy allow you to simulate plugin contexts and test your logic in isolation. For live debugging, use the Plugin Registration Tool’s Profiler to capture and replay plugin executions in Visual Studio — especially invaluable for tracking down tough bugs in complex solutions.

Common Pitfalls and How to Avoid Them

  • Infinite loops (Depth checks and careful design)
  • Null reference errors (Always check if fields exist before using them)
  • Misregistered steps (Double-check your registrations)
  • Security exceptions (Run plugins under the correct user or with the right privileges)
  • Performance issues (Keep plugins fast, use filtering attributes)
  • Bulk data handling (Plugins must handle high-volume scenarios gracefully)

Latest Features and Innovations

The plugin model keeps evolving. With features like Custom APIs, seamless Azure integration, and robust DevOps tooling, it’s easier than ever to build maintainable, enterprise-ready logic in Dataverse.

Final Thoughts

Mastering plugins is a journey — from writing your first validation handler to architecture complex integrations that power the world’s largest enterprises. The techniques and tips here come from real projects, real support escalations, and plenty of lessons learned the hard way. If you embrace best practices, automate your deployments, and always keep performance in mind, plugins will be your secret weapon for building systems that truly deliver.

Happy coding, and may your plugins always be fast, safe, and bug-free!

Want more deep dives on Dynamics 365 development? Let me know what topics to cover next!

Friday, July 11, 2025

Model Context Protocol (MCP) + Dataverse: The Next Leap for AI and the Power Platform


If you’re even a little bit invested in Power Platform, you’ve probably seen the Model Context Protocol (MCP) popping up in community posts, new features, and the Microsoft docs. If you’re wondering, “Is this just another buzzword, or does it actually make my life easier?” — this post is for you!

Let’s break down what MCP is, what you can do with it (hint: a lot!), and why this matters for every maker, developer, and AI enthusiast on the platform.

MCP is a new open protocol from Microsoft that lets Large Language Model (LLM) applications — like Copilot Studio, Claude, VS Code Copilot — connect securely and natively to enterprise data sources like Dataverse. This means that your AI agents can “see” and work with your real Dataverse data, safely and efficiently, with no custom connectors or APIs needed.

Learn more: Connect to Dataverse with Model Context Protocol (preview)

  • No more manual queries: Just ask questions in natural language — “How many leads are active?” or “Show me a chart of cases by city” — and your agent (Claude, Copilot, etc.) does the heavy lifting.
  • Instant insights and updates: You can fetch, update, and create Dataverse records as simply as sending a chat message.
  • Build bots and automations faster: Tools like Copilot Studio can now “think” in real time with your data — great for building conversational agents and process automations.
  • Less code, more power: You can do all of this without needing to write FetchXML, SQL, or custom code.
  • Future-proof integration: Any AI or LLM tool supporting MCP can plug into your Dataverse data — opening up a huge ecosystem of smart, connected tools.

Here’s just a taste of what’s possible right now (and it’s still just in preview!):

  • List all your tables“Show me all tables in Dataverse.”
  • Describe schema“Describe the account table.”
  • Read/query data“How many contacts live in London?”
  • Create/update records“Add a new contact: John Smith, email john@contoso.com.”
  • Build charts instantly“Create a pie chart showing opportunities by owner.”
  • Integrate knowledge sources“What’s the latest update from the product knowledge base?”

Basically, you can talk to your database, and it talks back with real answers, records, or charts — no code, just conversation.

How to Set Up MCP with Dataverse (Step by Step)

This is easier than you think. Here’s the process, based on Microsoft’s official docs :

Prerequisites:

  • Dataverse environment (Power Platform, Power Apps, or Power Automate)
  • VS Code installed (for advanced setup)
  • Claude Desktop (optional, but great as an MCP client)
  • .NET SDK 8.0 (for the MCP server local proxy)
  • Your Dataverse tenant ID
  • Dataverse connection (created in Power Automate)

From the official documentation, Dataverse MCP tools include:

  • create_record — Insert a row into a table
  • describe_table — Get table schema
  • execute_prompt — Run a predefined prompt
  • list_knowledge_sources — Show available knowledge sources
  • list_prompts — List prompts
  • list_tables — List available tables
  • read_query — Read data from tables
  • retrieve_knowledge — Query a knowledge source
  • update_record — Update a record

You can enable/disable each tool in your MCP config, so you’re always in control.

  • Preview Feature: As of mid-2025, MCP with Dataverse is still in preview — don’t use in production just yet!
  • Security: Make sure you understand the permissions you grant your AI client.
  • Customization: Tune which tools you expose, and set your own prompts/knowledge sources for maximum flexibility.

Model Context Protocol (MCP) is the next frontier for Power Platform, AI, and no-code/low-code automation. You can connect any MCP-enabled AI client (Copilot, Claude, custom bots) to Dataverse and get natural, conversational access to your enterprise data.

No more clunky queries. No more endless charts. Just instant answers, insights, and updates — straight from your data, with the power of AI.

A big thank you to the amazing video guide creator
Nathan Rose — your step-by-step walkthrough made the whole process so much more approachable and fun for the community.

https://youtu.be/IkBRy8bVtrc?si=CZFlaY36Ojap15GM

Thursday, July 10, 2025

How to Master Solution Layering and Troubleshoot Customization Conflicts in Dynamics 365 CRM


If you’ve ever deployed a solution to a Dynamics 365 CRM environment only to find your changes don’t show up, or something strange happens with forms or fields, you’re not alone. Almost every Dynamics admin or customizer has run into the mysterious world of solution layering. It’s not always intuitive, but understanding how solution layers work is absolutely key for troubleshooting post-deployment issues and building a sustainable ALM (Application Lifecycle Management) process.

Let’s break down what solution layering is, how conflicts can occur, and how to confidently resolve them.

Solution layering refers to the way Dynamics 365 (and Power Platform/Dataverse) manages multiple sets of customizations, especially when you have more than one solution (managed or unmanaged) touching the same component.

Every customizable object, like a form, view, or field, can have multiple “layers” of configuration applied. The platform keeps track of these layers and uses a clear order to decide what users will see and how components behave.

  1. System (Base) Layer:
    The lowest layer. This is the original, out-of-the-box state ,think of it as the bedrock for every component.
  2. Managed Solution Layers:
    Each imported managed solution gets its own layer. Managed layers stack on top of the system layer in the order they’re imported. The most recent one always sits above earlier ones.
  3. Unmanaged Layer:
    The very top. Any direct customizations made in the environment (through the UI, or via unmanaged solutions) live here. There is only one unmanaged layer per component, and the latest change always wins in this layer.

Why does this matter? Because only the topmost value (or a merge of layers, depending on the component) is active at runtime. This is why the changes you just imported sometimes seem to “disappear” or get overridden by something you didn’t expect.

Let’s say you install a third-party managed solution that customizes the Account form, maybe it adds a couple of new sections. Later, you deploy your own managed solution, which also customizes that Account form (perhaps adding a new section for internal use).

  • At runtime, the Account form merges customizations from both solutions, unless they directly conflict (for example, both try to change the header text). In that case, the topmost layer “wins.”
  • If someone makes a direct change in production (for instance, hiding a field to fix a quick issue), that unmanaged layer sits above everything else, even above your newly-deployed managed solution.

Common Example:
You deploy a managed solution expecting to see a new field on the form, but it’s not visible to users. You open the solution layers viewer and find an unmanaged change sitting on top (maybe a previous quick fix), which is hiding your field.

  • Some things merge:
    For example, if two managed solutions add different fields to the same form, both fields are visible, because those additions merge.
  • Some things overwrite:
    If two solutions provide a button or field with the same name/ID, or try to set a property like the display name or visibility, the “last one wins.” The topmost solution layer’s value is what the user will see.
  • Unmanaged layer always wins:
    Any direct changes made in the environment (the unmanaged layer) always take precedence. That’s why making direct changes in production is risky, it can override everything below.

How to Troubleshoot with the Solution Layers Tool

Dynamics 365 includes a powerful tool for investigating component layering:

  1. Go to the Power Apps Maker portal
  2. Find the component (form, view, field, etc.) you’re troubleshooting
  3. Select it and choose “See solution layers”

You’ll see all the layers, in order, and can review what each solution changed. Properties that were altered by a solution are highlighted.

Pro tip: If you can’t see your recent change in production, check here first. If there’s an unmanaged layer on top, that’s almost always the culprit.

Unmanaged customizations are a frequent cause of “why isn’t my solution working?” problems. For instance:

  • A System Customizer makes a “quick fix” to a form in production, creating an unmanaged layer.
  • You deploy a managed solution to update that same form, but your changes don’t appear, because the system uses the unmanaged version as the active layer.

How to fix:

  • Either incorporate that unmanaged change into your managed solution and redeploy
  • Or: Use “Remove Active Customizations” to delete the unmanaged layer for that component (be aware: this discards those ad-hoc changes!)

Warning: If the unmanaged layer added fields with data, removing it will remove the field and its data.

Resolving Managed Solution Conflicts

When two managed solutions conflict (maybe both add a field with the same name, or try to change the same form property), you have a few options:

  1. Manage Layer Order
    Re-import the solution you want to take precedence. (Remember, the most recently imported managed solution is on top.)
  2. Adjust the Customizations
    If you own both solutions, tweak them so they don’t overlap (use unique names or separate component responsibilities).
  3. Use a Patch or Hotfix Solution
    If you can’t remove the “problem” managed solution (e.g., it’s a core or third-party solution), create a tiny managed patch or hotfix solution. This patch will layer above, overriding the problematic setting or property.
  4. Uninstall or Clean Up
    As a last resort, uninstall the managed solution causing the issue, but only if nothing else depends on it.

Another layering-related headache: Sometimes you can’t uninstall or upgrade a solution because something else (another solution or unmanaged change) is using its components. You’ll usually get a descriptive error listing the dependencies.

  • Use the solution layers viewer to see what’s on top of the component you’re trying to remove.
  • Remove or reconfigure any dependent solutions or unmanaged changes first.

Solution layering isn’t just a problem to solve, it’s a powerful tool if you plan for it.

  • Modular design:
    Have a base managed solution for your core entities, and layer feature-specific managed solutions on top. Teams can work independently as long as they avoid overlapping components.
  • Safe rollbacks:
    If you need to remove a feature, you can just uninstall its solution — everything beneath remains intact.
  • Hotfixes:
    Emergency patch needed? Deploy a managed patch solution. It sits on top, overrides what’s needed, and can be rolled back easily.

Best Practices & Tips

  • Always use the Solution Layers viewer when troubleshooting.
  • Document which solutions “own” which parts of your system to avoid accidental overlap.
  • Avoid direct unmanaged changes in production — if you must, plan to integrate them back into a managed solution and remove the unmanaged layer ASAP.
  • Check Solution Import logs: These can warn you if components were skipped or a conflict occurred.
  • Test all changes in a non-prod environment first. Removing or reordering solution layers can have side effects.

Solution layering in Dynamics 365 CRM can feel confusing at first, but it’s a robust system for handling complex, multi-team, and even multi-vendor deployments. The trick is to respect the order of layers, avoid unmanaged “quick fixes” in production, and always use the tools Microsoft provides to see what’s going on.

If you ever run into a situation where “my change isn’t showing up” or “something broke after a deployment,” the solution layers tool should be your first stop. With a clear ALM strategy and a little practice, you’ll turn layering from a headache into a feature that helps you build, troubleshoot, and evolve your CRM with confidence.

Extra Reading & Resources:

Got a layering war story or pro tip? Drop it in the comments!

Sri Lanka .NET 
                Forum Member