Wicked Smart Data
LearnInsightsAboutContact
Sign InLet's Build
LearnInsightsAboutContact
Sign InLet's Build
Wicked Smart Data

Intelligence, automation, and expert execution — plus an elite library of free knowledge. We turn complexity into competitive advantage.

Start a conversation

Platform

  • Learning Paths
  • Insights
  • RSS Feed

Company

  • About
  • Contact
  • Work With Us

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Wicked Smart Data. All rights reserved.

Intelligence · Automation · Advantage

All Insights
Power Apps

Configuring Dataverse Solution Segmentation and Component Dependencies: Splitting Model-Driven App Customizations Across Multiple Solutions for Modular ALM and Safe Deployment

Monolithic Power Platform solutions create fragile, risky deployments — but splitting customizations across solutions requires understanding how Dataverse tracks component ownership, resolves layer conflicts, and enforces dependencies. This deep-dive lesson teaches you how to design a layered solution architecture, manage cross-solution dependencies safely, and build an ALM pipeline where teams can ship independently without stepping on each other.

🔥 Expert29 min readOct 10, 2026Updated Oct 10, 2026
Configuring Dataverse Solution Segmentation and Component Dependencies: Splitting Model-Driven App Customizations Across Multiple Solutions for Modular ALM and Safe Deployment
On this page
  • Introduction
  • Prerequisites
  • How Dataverse Actually Tracks Component Ownership
  • Component Types and Their Segmentation Behavior
  • Designing a Layered Solution Architecture
  • Layer 1: Publisher Foundation (One per Tenant/Org)
  • Layer 2: Data Model Layer (One or More, Per Domain)
  • Layer 3: Business Logic Layer
  • Layer 4: UI Layer
  • Layer 5: App Layer
  • The Complete Architecture at a Glance
  • Managing Cross-Solution Dependencies
  • Understanding Solution Dependencies vs. Component Dependencies
  • Resolving the "Missing Dependent Component" Error
  • Avoiding Circular Dependencies
  • Handling Shared Choice Columns
  • Adding Table Components Selectively
  • In the Data Model Solution
  • In the UI Solution
  • The "Add Required Components" Button and Why It's Dangerous
  • Solution Patching and Cloning for Hotfixes
  • What Patches Are and When to Use Them
  • Cloning vs. Patching: Choosing the Right Tool
  • Enforcing Architecture with Managed Properties
  • Practical Managed Property Recommendations by Layer
  • Environment Variable Strategy in a Multi-Solution Architecture
  • Hands-On Exercise
  • Setup
  • Segmentation Task
  • Verification
  • Advanced Challenge
  • Common Mistakes & Troubleshooting
  • Mistake 1: Including Forms in the Data Model Solution
  • Mistake 2: One Giant Security Role Across All Tables
  • Mistake 3: Forgetting That Solution Patches Don't Apply to Unmanaged Solutions
  • Mistake 4: Deploying Solutions Out of Order
  • Mistake 5: Not Reconciling Patches Before Major Releases
  • Mistake 6: Accidental Component Duplication Across Solutions
  • Troubleshooting: Using Solution Checker for Dependency Analysis
  • Summary & Next Steps
  • Configuring Dataverse Solution Segmentation and Component Dependencies: Splitting Model-Driven App Customizations Across Multiple Solutions for Modular ALM and Safe Deployment

    Introduction

    Here's a scenario you've probably lived through: a minor UI change to a model-driven app form gets bundled into the same solution as a critical security role update, a new table schema, and three Power Automate flows. The whole thing gets exported, imported into production, and two hours later someone reports that a field that's been working fine for a year now throws a validation error. You dig in and discover that the "minor UI change" imported a managed layer for a business rule that silently overwrote a customization that was sitting in the unmanaged layer of the target environment. The rollback takes half a day.

    This is the tax you pay for treating solutions as monolithic deployment packages. As your Dataverse implementations grow beyond a handful of tables and a single app, the solution architecture becomes just as important as the data model or the UI design. Getting it wrong doesn't just slow you down — it makes production deployments unpredictable and rollbacks painful.

    By the end of this lesson, you'll understand how to deliberately segment Dataverse customizations across multiple solutions, manage component dependencies in a way that prevents deployment surprises, and build an ALM pipeline that lets individual teams ship independently without stepping on each other. This is the kind of architectural knowledge that separates Power Platform consultants who get called in to fix disasters from the ones who prevent them.

    What you'll learn:

    • How solution segmentation works at the Dataverse platform level, including how component ownership and layering interact
    • How to design a multi-solution architecture: base layers, capability layers, and app layers
    • How to identify and resolve cross-solution component dependencies without creating circular references
    • How to use solution patching and cloning for hotfix scenarios without breaking your main deployment pipeline
    • How managed properties interact with solution boundaries to enforce architectural contracts between teams

    Prerequisites

    You should be comfortable with the fundamentals of Dataverse solutions — specifically how managed and unmanaged solutions differ, what solution layers are, and how component metadata is tracked. If you need a refresher, read Solutions for Model-Driven Apps: Publishers, Managed vs Unmanaged, and Solution Layering before continuing. You should also understand the basics of Dataverse Fundamentals: Tables, Columns, and Rows Explained for Power Apps Makers and have hands-on experience building model-driven apps.


    How Dataverse Actually Tracks Component Ownership

    Before we talk strategy, we need to talk mechanics. You can't design a sound multi-solution architecture if you don't understand how the platform resolves conflicting definitions of the same component.

    Every component in Dataverse — a table, a column, a form, a view, a security role, a business rule, a site map — has a solution component record that links it to one or more solutions. When you add a component to a solution, you're creating a row in the SolutionComponent table that says "this component belongs to this solution." A single component can belong to multiple solutions simultaneously. That's not a bug; it's by design.

    What matters for deployment is the layering order. When you import a managed solution into an environment, Dataverse places it in a managed layer below any unmanaged customizations. If two managed solutions both define the same form, the one imported last wins, and this is controlled by the solution's position in the layer stack. You can inspect this in the Power Platform admin center under Solutions > [your solution] > Solution layers for any component.

    The critical insight is this: component ownership is per-solution-component record, but the effective definition is resolved at runtime from the layering stack. This means you can have a form defined in a base managed solution and then have that same form modified by a second managed solution layered on top. The second solution "patches" the form definition without replacing the base. This is the legitimate, intentional use of layering — but it only works safely if you understand the dependency chain.

    Key insight

    When a component exists in multiple solutions, removing or upgrading one solution doesn't automatically revert to the previous layer's definition. The platform will use whatever definition survives in the remaining layers. This is why testing solution removal is just as important as testing solution import.

    Component Types and Their Segmentation Behavior

    Not all component types behave the same way when segmented across solutions. Here's what you need to know for model-driven app work:

    Tables are segmented at the component level. When you add a table to a solution, you can choose to include the entire table (all columns, forms, views, relationships) or just specific sub-components. This distinction is huge. If you add a table with "Include all components," any change to any part of that table — a new column, a form edit, even a chart — gets dragged into that solution. For a platform or base layer solution, that's often what you want. For a capability-specific solution, it's almost always wrong.

    Forms and Views are independent components. A form has its own solution component record, separate from the table that contains it. This means you can add Account Main Form to Solution A and Account Quick View Form to Solution B, and they'll deploy independently. This is the primary mechanism that makes UI segmentation possible.

    Security Roles are atomic — you either include the whole role or you don't. You can't segment individual privilege rows across solutions. This has significant implications for role-based security design, which we'll cover in the security layer section.

    Business Rules are independent components, like forms. Each business rule has its own component record and can be placed in any solution independently of its parent table.

    Relationships are interesting. A one-to-many relationship is "owned" by the primary entity's solution. When you add a relationship to a solution, both the relationship definition and the resulting lookup column on the related table get pulled in together. This matters when you're trying to keep your data model layer clean — adding a relationship always brings metadata from both tables into scope.


    Designing a Layered Solution Architecture

    The most effective multi-solution architectures follow a layered pattern with clear responsibilities. Think of it like a dependency graph: each layer can depend on components from layers below it, but never the other way around. Circular dependencies between solutions are a production disaster waiting to happen.

    Here's the architecture pattern that works for serious enterprise implementations:

    Layer 1: Publisher Foundation (One per Tenant/Org)

    This solution exists purely to establish your publisher prefix and any shared configuration that literally everything else depends on. In practice, this often means:

    • Environment variables with no connection references (infrastructure settings like API endpoints, feature flags)
    • Shared Choice (Option Set) definitions used across multiple tables
    • The publisher record itself

    Keep this solution almost empty. Its value is establishing a consistent prefix and avoiding the situation where different solutions are built against different publishers, creating messy naming collisions. For a real-world example: a financial services firm might call this FS_Foundation with publisher prefix fs.

    Layer 2: Data Model Layer (One or More, Per Domain)

    This is where table definitions, columns, and relationships live. The key decision here is how to slice your domain. For a CRM-style implementation, you might have:

    • FS_CoreEntities — Accounts, Contacts, and their core columns and relationships
    • FS_LoanProcessing — Loan Application, Loan Product, and related tables
    • FS_ServiceManagement — Case, Service Contract, SLA tables

    Each data model solution should include tables with selected components only — specifically the table definition, columns, and relationships. Do not include forms or views in data model solutions. Here's why: forms and views are UI concerns. Keeping them in the data model layer means that every UI change requires re-exporting and re-importing a solution that contains your core schema. Schema changes carry significant risk; you don't want a button relabeling exercise to touch the same package.

    Warning

    When you add a table to a solution using "Add required components," Dataverse will pull in every component that the selected component depends on — including forms and views that you may not want in this solution. Always review the component list after using "Add required components" and remove anything that shouldn't be in this layer.

    When you add just the table definition (not all components), you're adding what Microsoft calls the table metadata — the entity record itself with properties like display name, ownership type, audit settings, and change tracking configuration. Columns and relationships are separate components that you add explicitly. This granular control is what makes real segmentation possible.

    Layer 3: Business Logic Layer

    Security roles, business rules, plugins, and workflow definitions. Some teams merge this with the data model layer for smaller implementations, but separating it pays dividends when you have:

    • Multiple developers working on business logic simultaneously
    • A compliance requirement that business rules can be audited and deployed independently
    • A scenario where the same data model supports multiple business rule sets (e.g., regional variations)

    For a loan processing scenario: FS_LoanBusinessLogic might contain the business rules for field validation on the Loan Application form, security roles scoped to loan officers and underwriters, and business process flow definitions.

    If you're building business process flows — the multi-stage guided process bars at the top of forms — note that they're often classified as business logic but have a hard dependency on the forms they appear on. We'll address this dependency resolution later.

    Layer 4: UI Layer

    Forms, views, charts, and dashboards. One solution per app or per functional area, depending on your team structure. For the loan processing example:

    • FS_LoanApp_UI — All forms and views for the loan processing app
    • FS_ServiceApp_UI — All forms and views for the service management app

    The UI layer has dependencies on both the data model layer (it needs the columns to exist to add them to forms) and the business logic layer (security roles determine what users see). Those dependencies flow one way: UI depends on data and logic, never the other way around.

    Tip

    Even if you have a single model-driven app at launch, set up separate UI layer solutions from day one. The cost is near-zero, and it prevents the very common mistake of having to untangle a monolith six months later when a second team needs to ship a new app independently.

    Layer 5: App Layer

    The model-driven app itself — the App Module component — lives here, along with its site map. This layer depends on everything below it, but nothing depends on it. That means you can update the app definition (add a page, rearrange the site map) without touching any other layer.

    A model-driven app has dependencies on forms, views, tables, and the site map. When you export the app layer solution, those components must exist in the target environment — either installed by their respective solutions or present as unmanaged customizations. The app definition itself doesn't bundle them; it just references them by ID.

    The Complete Architecture at a Glance

    ┌─────────────────────────────────────────┐
    │  Layer 5: App Layer                     │
    │  FS_LoanApp, FS_ServiceApp              │
    │  (App Module, Site Map)                 │
    └─────────────────┬───────────────────────┘
                      │ depends on
    ┌─────────────────▼───────────────────────┐
    │  Layer 4: UI Layer                      │
    │  FS_LoanApp_UI, FS_ServiceApp_UI        │
    │  (Forms, Views, Charts, Dashboards)     │
    └─────────────────┬───────────────────────┘
                      │ depends on
    ┌─────────────────▼───────────────────────┐
    │  Layer 3: Business Logic Layer          │
    │  FS_LoanBusinessLogic                   │
    │  (Security Roles, Business Rules, BPFs) │
    └─────────────────┬───────────────────────┘
                      │ depends on
    ┌─────────────────▼───────────────────────┐
    │  Layer 2: Data Model Layer              │
    │  FS_CoreEntities, FS_LoanProcessing     │
    │  (Tables, Columns, Relationships)       │
    └─────────────────┬───────────────────────┘
                      │ depends on
    ┌─────────────────▼───────────────────────┐
    │  Layer 1: Foundation                    │
    │  FS_Foundation                          │
    │  (Publisher, Choices, Env Variables)    │
    └─────────────────────────────────────────┘
    

    Managing Cross-Solution Dependencies

    Dependencies between solutions are where most teams run into trouble. Dataverse tracks dependencies automatically in the Dependency table, and you can query them — but you can't always control them intuitively through the UI.

    Understanding Solution Dependencies vs. Component Dependencies

    There's an important distinction here. A solution dependency is declared explicitly: Solution B declares that it requires Solution A to be installed first. A component dependency is implicit: if Form X references Column Y, and Column Y is in a different solution than Form X, then the solution containing Form X has an implicit dependency on the solution containing Column Y.

    The platform enforces component dependencies during import. If you try to import FS_LoanApp_UI into an environment where FS_LoanProcessing (which contains the Loan Application table) hasn't been installed yet, the import will fail with a dependency error listing every missing component.

    You can view these dependencies before export. In the solution editor, go to the component and look for Show Dependencies. For a form, this will list every column referenced in the form layout, every business rule active on that form's scope, and any related entity definitions needed for subgrids.

    Note

    The Power Platform CLI command pac solution check will analyze a solution package and surface dependency violations before you even attempt an import. Building this into your CI/CD pipeline catches issues at build time rather than at production import time.

    Resolving the "Missing Dependent Component" Error

    When a solution import fails with a missing dependency, you have three options:

    Option 1: Import the missing solution first. This is always the right answer when you control both solutions. Add the missing solution to your deployment pipeline at an earlier stage. If FS_LoanApp_UI needs columns from FS_LoanProcessing, then your pipeline deploys FS_LoanProcessing → FS_LoanBusinessLogic → FS_LoanApp_UI → FS_LoanApp in sequence.

    Option 2: Move the component into the current solution. Sometimes a dependency is accidental — a column that really belongs to your UI layer's domain ended up in a data model solution by mistake. Evaluate whether the component is in the right place before deciding to always import it as a prerequisite.

    Option 3: Use solution patches to stage the dependency. In rare cases where you need to deploy an update to Solution B without updating Solution A, you can create a patch of Solution A that includes just the new component, deploy the patch first, then deploy Solution B. This is a valid hotfix pattern but creates technical debt if overused.

    Avoiding Circular Dependencies

    Circular dependencies are the solution architecture equivalent of deadlock. Solution A needs a component from Solution B, and Solution B needs a component from Solution A. The platform won't let you import either without the other.

    The most common cause is security roles that reference components from multiple domains. A security role that grants access to both Account and Loan Application tables creates an implicit dependency on both FS_CoreEntities and FS_LoanProcessing. If your security role is in FS_LoanBusinessLogic (which depends on FS_LoanProcessing) and your UI layer also needs account-level security that's defined somewhere else, you can end up in a tangle.

    The solution is to follow the security role per solution layer principle: define security roles in the layer that owns the components being secured. The Loan Processing business logic layer owns the loan officer role, which has permissions to loan-specific tables. The Core Entities layer owns a base contact manager role with account/contact permissions. A user's effective privileges come from having both roles assigned — not from one monolithic role that you'd have to split between solutions.

    This approach aligns with how Dataverse Security: Business Units, Security Roles, and Teams recommends thinking about role composition as additive rather than monolithic.

    Warning

    Never create a security role in Solution A that explicitly grants CREATE privileges on a table defined in Solution B if Solution B is supposed to be at a higher layer. This creates an upward dependency that violates your architecture and will cause deployment failures in environments where Solution B hasn't been installed yet.

    Handling Shared Choice Columns

    Global Choice (Option Set) columns are a common dependency trap. If multiple tables in different solutions all reference the same global choice — say, a shared Status Category choice used by both Accounts and Loan Applications — that choice must exist in a layer below both tables.

    This is exactly what the Foundation layer is for. Put all shared global choices in FS_Foundation. Each domain-specific data model solution depends on the Foundation layer. If a choice is only used by components in a single domain solution, it's fine to define it in that solution. But the moment a choice is referenced by two solutions at the same layer, it needs to move down.

    The same principle applies to Designing a Dataverse Data Model: Relationships, Lookups, and Choice Columns — the design of the data model itself affects which components can be cleanly segmented.


    Adding Table Components Selectively

    The practical skill of solution segmentation is knowing exactly which components to add to which solution. Let's walk through a realistic scenario: you're adding the fs_loanapplication table to FS_LoanProcessing and the main form to FS_LoanApp_UI.

    In the Data Model Solution

    Navigate to FS_LoanProcessing → Add existing → Table. Select Loan Application. Here's the critical decision point: the dialog will ask you what to include. Choose "Select components" rather than "Include all components."

    In the component selection screen, check:

    • The table itself (always required)
    • All columns you want this solution to own
    • All relationships originating from this table

    Do not check:

    • Forms (those go in FS_LoanApp_UI)
    • Views (same)
    • Charts, dashboards
    • Business rules (those go in FS_LoanBusinessLogic)

    After adding the table with selected components, verify the solution contents. You should see Loan Application (Table) in the list, and when you expand it, you should see columns and relationships — but no forms or views.

    In the UI Solution

    Navigate to FS_LoanApp_UI → Add existing → Table → select Loan Application → "Select components" → check only the forms and views you're managing in this solution.

    Now there's a subtlety: when you add a form to a UI solution, Dataverse adds both the form component and a reference to the parent table. The table reference in the UI solution is just a pointer — it's not redefining the table, just saying "this form belongs to this table." When you export and import this solution, the table must already exist in the target environment (installed by FS_LoanProcessing). If it doesn't, the import fails.

    Tip

    After setting up this split, open both solutions side by side and compare their component lists. A common mistake is accidentally adding the full table (with all components) to the UI solution, which means the same form definition now lives in both solutions. That's not a blocker, but it creates confusion about which solution "owns" the form and makes future updates error-prone.

    The "Add Required Components" Button and Why It's Dangerous

    Every solution editor has an Add Required Components button. It analyzes selected components and automatically adds everything they depend on to the current solution. For a form, this could mean pulling in every column referenced in the form, every related table referenced in subgrids, and potentially cascading into dozens of additional components.

    This button is useful for creating a self-contained solution from scratch (like an ISV packaging their entire product), but it's toxic for segmented architecture. If you add required components for a form in your UI solution, you'll end up with table definitions, column definitions, and relationship definitions that should live in your data model solution — now duplicated in your UI solution. Future schema changes will fail because the platform sees conflicting definitions.

    Use Add Required Components only when you've intentionally decided to make a solution self-contained. For segmented ALM, add components manually and rely on your deployment pipeline to ensure prerequisites are installed.


    Solution Patching and Cloning for Hotfixes

    Your carefully designed multi-solution architecture works great for planned releases. But production has a way of requiring urgent fixes on a Friday afternoon, when your main solution is mid-way through a feature development sprint in dev. Solution patches are the answer.

    What Patches Are and When to Use Them

    A patch is a child solution of a specific solution version. When you create a patch of FS_LoanApp_UI v1.0.0.0, you get FS_LoanApp_UI_Patch_[timestamp] that inherits all components of the parent but only exports changes you explicitly add to the patch.

    In the Power Platform Maker Portal, open the parent solution and select Clone a Patch. Give the patch a meaningful name like FS_LoanApp_UI_Hotfix_StatusField. Now add only the form that needs the emergency fix. Export this patch as managed, import it into production. The patch layers on top of the parent solution, overriding only the specific form.

    The limitation: patches must be rolled up into the parent solution eventually. Microsoft recommends doing this by cloning the parent solution to create the next version, which absorbs all patches. The command is Clone Solution from the parent solution — this creates a new version (e.g., 1.1.0.0) that includes all current patches baked in. Deploy this cloned solution to replace both the parent and all its patches.

    Warning

    Do not create more than one patch at a time for the same parent solution. The platform allows it, but the resulting layer stack becomes almost impossible to reason about. If you need two concurrent hotfixes, add both to the same patch. If you've already shipped a patch and need another, clone the solution first to roll up the existing patch, then create a new patch of the new version.

    Cloning vs. Patching: Choosing the Right Tool

    Scenario Use
    Emergency single-component fix Patch
    Planned minor release with multiple changes Clone + increment version
    Major schema change New version in main solution, full pipeline
    ISV shipping an update Clone, increment to new version
    Team wants to test a risky change in isolation Separate temporary solution, merge manually

    Enforcing Architecture with Managed Properties

    Managed properties are the enforcement mechanism that turns your architectural decisions into platform constraints. Without them, your carefully designed layer structure is just a convention — any developer with environment access can break it.

    When your data model solutions are exported as managed (which they should be in non-development environments), you can configure managed properties on each component to control what downstream solutions can modify.

    For a table, navigate to the table in the solution → Managed Properties. You'll find options like:

    • Allow customization — whether any property of this table can be changed by higher-layer solutions
    • Can be related entity in a relationship — whether other solutions can create new relationships to this table
    • Allow forms to be customized — specific to form components

    For columns, you can control whether their display name, requirement level, or field-level security settings can be changed downstream.

    The practical use case: if your foundation team owns the fs_loanapplication table schema and you don't want the UI team accidentally adding columns through their UI solution, set Allow new forms to false and Display name can be modified to false on the managed table. Now when the UI solution is imported, those properties are locked.

    This is deeply connected to the topic in Configuring Dataverse Managed Properties and Solution Component Locking: Controlling Customizability, Preventing Downstream Modifications, and Enforcing ISV-Grade Solution Boundaries in Model-Driven Apps, and if you're building an ISV product or a platform solution consumed by multiple teams, that's required reading.

    Key insight

    Managed properties only take effect when a solution is installed as managed. In your development environment, where solutions live as unmanaged, managed properties aren't enforced. This is intentional — devs need freedom. But it means your managed property constraints are only tested when you actually deploy managed solutions to a validation environment. Build that validation step into your pipeline.

    Practical Managed Property Recommendations by Layer

    Foundation layer: Lock almost everything. Publishers, shared choices, and environment variable schemas should be immutable downstream. Set Allow customization = false on all choice columns exported from this layer.

    Data model layer: Lock column schemas (data type, required level, auditing settings) but allow display name changes and form/view additions. You want the downstream UI layer to be able to add columns to forms — you just don't want it redefining the column type.

    Business logic layer: Security roles in managed solutions can't be directly modified by unmanaged customizations in the same environment — this is actually the default behavior for managed security roles. Don't fight it; use it. Allow role additions (new roles created in higher layers) but lock the managed roles themselves.

    UI layer: Keep forms and views customizable if you have a customer-facing deployment where customers may want to adjust their UI. Lock them if you're deploying a standardized internal enterprise solution.


    Environment Variable Strategy in a Multi-Solution Architecture

    Configuring Dataverse Environment Variables in Model-Driven App Solutions deserves special attention in the context of solution segmentation.

    Environment variables are solution components just like tables and forms. Their definitions (schema) live in the solution; their values live in a separate EnvironmentVariableValue record that is not exported with the solution. This design is intentional — it lets you define the variable in your dev solution and set different values in UAT and production without needing to modify the solution package.

    The segmentation rule for environment variables: define them in the layer that uses them. If an environment variable controls a setting for your loan processing business logic (like a max loan amount threshold), it belongs in FS_LoanBusinessLogic. If it controls a UI setting (like a dashboard ID to display by default), it belongs in FS_LoanApp_UI.

    The one exception: variables shared across layers (like a base API URL used by multiple solutions) belong in the Foundation layer.

    Tip

    Create a naming convention for environment variables that encodes the layer. For example, fs_foundation_api_endpoint, fs_loan_maxloanamount, fs_loanui_defaultdashboardid. This makes it immediately obvious which solution owns which variable when you're debugging a deployment issue six months from now.


    Hands-On Exercise

    In this exercise, you'll take a monolithic solution that contains a complete model-driven app implementation and split it into a proper layered architecture. You'll need a Power Platform developer environment and the Power Platform CLI installed.

    Setup

    Create a developer environment if you don't have one. In that environment, create a single solution called Monolith with publisher prefix ex. Inside it, create:

    1. A table called Training Request with columns: Title (text), Requested Date (date), Status (choice: Pending/Approved/Rejected), Approver (lookup to User), Training Type (global choice: Technical/Leadership/Compliance)
    2. A Main Form for Training Request with all columns
    3. A default Active Training Requests view
    4. A business rule that makes Approver required when Status is Approved
    5. A security role called Training Manager with Create/Read/Write/Delete on Training Request
    6. A model-driven app called Training Portal with the Training Request table in its site map

    Export Monolith as managed to a file.

    Segmentation Task

    Now create four new solutions with the same publisher:

    EX_Foundation: Move the Training Type global choice here. Export as managed and import to a second developer environment.

    EX_TrainingData: Add the Training Request table with selected components only — just the table definition, all columns, and no forms or views. Also add the lookup relationship to User. Export as managed and import to the second environment.

    EX_TrainingLogic: Add the Training Request business rule and the Training Manager security role. Note that when you add the business rule, Dataverse will indicate that the Training Request table is a dependency. This is expected — it will resolve through EX_TrainingData. Export as managed and import to the second environment.

    EX_TrainingUI: Add the Training Request table with selected components — this time selecting only the Main Form and the Active Training Requests view. Then add the model-driven app itself. Export as managed and import to the second environment in this order.

    Verification

    In the second environment, after importing all four solutions in layer order, verify:

    1. Open the Training Portal app — it should load without errors
    2. Navigate to Training Requests, create a new record, set Status to Approved — the business rule should fire and make Approver required
    3. Check the solution component list for each solution in the second environment. Training Request (Table) should appear in EX_TrainingData. The Main Form should appear only in EX_TrainingUI.
    4. Try to edit the Training Type global choice in the second environment. Since it came from a managed solution, you shouldn't be able to modify the option values (only add new ones if managed properties allow it).

    Advanced Challenge

    Using the Power Platform CLI, run the following to inspect dependencies:

    pac solution check --path ./EX_TrainingUI.zip --outputDirectory ./results
    

    Review the output. You'll see the dependency chain that the platform would validate during import. Now try exporting EX_TrainingUI without first deploying EX_TrainingData to a third environment and observe the specific error message. Understanding what these errors look like helps you diagnose them faster in real deployments.


    Common Mistakes & Troubleshooting

    Mistake 1: Including Forms in the Data Model Solution

    Symptom: Every form update requires a new version of the data model solution to be deployed, creating unnecessary risk for schema change deployments.

    Fix: Audit your data model solutions' component lists. Any form or view components should be moved to the UI layer. Use the Remove component option (not delete) to remove them from the data model solution without deleting the underlying artifact.

    Mistake 2: One Giant Security Role Across All Tables

    Symptom: Security role changes require deploying the solution that contains your core table schema.

    Fix: Split roles by domain, as described in the dependency section. Users get multiple roles assigned additively. If you have complex permission requirements spanning domains, consider using Dataverse Security: Business Units, Security Roles, and Teams access teams for record-sharing scenarios that don't need permanent role assignments.

    Mistake 3: Forgetting That Solution Patches Don't Apply to Unmanaged Solutions

    Symptom: You create a patch of a solution, but in your dev environment (where everything is unmanaged), the patch does nothing — changes in the patch don't appear to be isolated.

    Fix: Patches are a managed solution mechanism. In dev environments, you typically work with unmanaged solutions. Test your patch workflow in a dedicated validation environment where you import managed solutions, not in dev. Don't confuse "the patch exists" with "the patch is being applied."

    Mistake 4: Deploying Solutions Out of Order

    Symptom: Import fails with "Missing required component: [component name] (type: Column)" even though you know that column exists somewhere in your source environment.

    Fix: Your deployment pipeline must enforce layer ordering. If you're using Azure DevOps or GitHub Actions with the Power Platform Build Tools, use task dependencies to ensure each solution deployment step depends on the previous one completing successfully. Never import solutions in parallel if there's any chance of dependency relationships between them.

    Mistake 5: Not Reconciling Patches Before Major Releases

    Symptom: You've accumulated three patches for a solution over six months. A major release fails because the new solution version conflicts with existing patch layers.

    Fix: Before any major release, clone the solution to absorb all existing patches into a new base version. Deploy the cloned version, which replaces both the original and all patches in a single import. Add this step to your release checklist.

    Mistake 6: Accidental Component Duplication Across Solutions

    Symptom: The same form appears in both the UI solution and the data model solution. After a UI solution update, the form reverts to an older definition.

    Fix: Investigate solution layers for the form component in the affected environment (Solutions > [solution] > [component] > See solution layers). Identify which solution's layer is winning and which is redundant. Remove the component from the solution where it doesn't belong. This often requires a managed solution update that removes the component from the incorrect solution.

    Troubleshooting: Using Solution Checker for Dependency Analysis

    The Power Platform Solution Checker doesn't just check code quality — it validates solution structure. For dependency-related issues, the most useful analysis is running the checker against individual solutions in isolation to see exactly what each solution declares as dependencies.

    You can also query the Dependency table directly via the Dataverse Web API:

    GET [org-url]/api/data/v9.2/dependencies?
      $filter=dependentcomponentbasesolutionid eq [solution-guid]
      &$select=dependentcomponentdisplayname,requiredcomponentdisplayname,
               requiredcomponentsolutionname
    

    This query returns every component in your solution and what it requires. Cross-reference the requiredcomponentsolutionname values with your architecture diagram. Any required component coming from a solution that's at the same layer as yours (not a lower layer) is a potential dependency problem.


    Summary & Next Steps

    Solution segmentation is not a nice-to-have for serious Power Platform implementations — it's the difference between an ALM process that scales with your team and one that creates production fear. The key principles to carry forward:

    Layer your architecture. Foundation → Data Model → Business Logic → UI → App. Dependencies always flow downward. If you find yourself tempted to create an upward dependency, something is in the wrong layer.

    Add components selectively. Use "Select components" rather than "Include all components" when adding tables to solutions. Manually verify your component lists before export.

    Own your dependency graph. Use Solution Checker, the Dependency API, and the solution layers viewer to understand what your solutions actually depend on — not just what you think they depend on.

    Use patches for hotfixes, clones for releases. Never let patches accumulate. Roll them up into new versions regularly.

    Enforce constraints with managed properties. Architectural conventions without enforcement are just suggestions. Managed properties make the platform itself your architecture guardian.

    From here, your natural next steps are to explore how Configuring Dataverse Managed Properties and Solution Component Locking gives you fine-grained control over what each layer can modify, and how Configuring Dataverse Environment Variables in Model-Driven App Solutions fits into your deployment pipeline for managing configuration across environments. You'll also want to integrate this layered architecture with your model-driven app security design, since the layer in which a security role lives determines how it can be managed and extended downstream.

    Solution architecture is one of those disciplines where experience compounds dramatically. The more implementations you design and debug, the better your instinct becomes for where a component belongs and what the downstream consequences of a design decision will be. Build that instinct deliberately — by instrumenting your deployments, studying your dependency graphs, and treating each production incident as a data point about your architecture's weak spots.

    Work With Us

    From insight to implementation

    Reading is the start. When you're ready to build the data, automation, or AI systems behind it, our team turns strategy into shipped results.

    Let's Build

    Model-Driven Apps & Dataverse

    Previous

    Configuring Dataverse Column Mappings for Relationship-Driven Record Creation: Auto-Populating Fields When Creating Child Records from Parent Forms in Model-Driven Apps

    Related Insights

    Power AppsPractitioner

    Configuring Dataverse Column Mappings for Relationship-Driven Record Creation: Auto-Populating Fields When Creating Child Records from Parent Forms in Model-Driven Apps

    25 min
    Power AppsExpert

    Configuring Dataverse Choices and Choice Columns: Global Option Sets, Multi-Select Columns, and Dependency Filtering in Model-Driven App Forms

    30 min
    Power AppsPractitioner

    Configuring Dataverse Activity Tables and Timeline Controls in Model-Driven Apps: Tracking Emails, Tasks, Appointments, and Custom Activities Against Records

    27 min

    On this page

    • Introduction
    • Prerequisites
    • How Dataverse Actually Tracks Component Ownership
    • Component Types and Their Segmentation Behavior
    • Designing a Layered Solution Architecture
    • Layer 1: Publisher Foundation (One per Tenant/Org)
    • Layer 2: Data Model Layer (One or More, Per Domain)
    • Layer 3: Business Logic Layer
    • Layer 4: UI Layer
    • Layer 5: App Layer
    • The Complete Architecture at a Glance
    • Managing Cross-Solution Dependencies
    • Understanding Solution Dependencies vs. Component Dependencies
    • Resolving the "Missing Dependent Component" Error
    • Avoiding Circular Dependencies
    • Handling Shared Choice Columns
    • Adding Table Components Selectively
    • In the Data Model Solution
    • In the UI Solution
    • The "Add Required Components" Button and Why It's Dangerous
    • Solution Patching and Cloning for Hotfixes
    • What Patches Are and When to Use Them
    • Cloning vs. Patching: Choosing the Right Tool
    • Enforcing Architecture with Managed Properties
    • Practical Managed Property Recommendations by Layer
    • Environment Variable Strategy in a Multi-Solution Architecture
    • Hands-On Exercise
    • Setup
    • Segmentation Task
    • Verification
    • Advanced Challenge
    • Common Mistakes & Troubleshooting
    • Mistake 1: Including Forms in the Data Model Solution
    • Mistake 2: One Giant Security Role Across All Tables
    • Mistake 3: Forgetting That Solution Patches Don't Apply to Unmanaged Solutions
    • Mistake 4: Deploying Solutions Out of Order
    • Mistake 5: Not Reconciling Patches Before Major Releases
    • Mistake 6: Accidental Component Duplication Across Solutions
    • Troubleshooting: Using Solution Checker for Dependency Analysis
    • Summary & Next Steps