---
title: Create business object from criteria
summary: Instantiates a business object from criteria and runs its create lifecycle through the active data portal when needed.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Framework.Core
reference_type: package
operation_id: OP-CORE-003
trigger: Caller invokes IDataAccess.CreateObject(criteria).
---

# Create business object from criteria

This operation is the framework's create pipeline, shared by both SQL-backed and API-backed criteria objects. It instantiates the business-object type associated with the criteria, runs the object's create hooks, and only reaches the data portal when the object's `BeforeCreate` phase actually queued work — a pure in-memory create is a first-class, expected path, not a fallback.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CORE-003 |
| **Trigger** | Caller invokes `IDataAccess.CreateObject(criteria)`. |
| **Inputs** | `IBusinessCriteria` or `IBusinessApiCriteria` instance with a populated `DataPortalInfo`. |
| **Outputs** | Newly created business object after `Create`/`BeforeCreate`/`AfterCreate`. |
| **Primary components** | `clsDataAccess.CreateObject(IBusinessCriteria)`, `clsDataAccess.CreateObject(IBusinessApiCriteria)` |
| **Entry point** | `SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb` |

## Steps

1. Validate that the caller supplied criteria.
   - If `inCriteria Is Nothing`, the method throws `SystemException` immediately.
2. Determine the business-object type and instantiate it.
   - The framework reads `inCriteria.GetType.DeclaringType`.
   - It creates the target object through `Activator.CreateInstance(dataType, True)` so non-public constructors are allowed.
   - The criteria object is assigned to `busObj.CriteriaObject`, and `busObj.OnInstantiation()` runs.
3. Prepare the create portal request.
   - The framework resolves the portal from `busObj.CriteriaObject.DataPortalInfo.PortalID`.
   - It creates a new portal request and assigns `PortalRequest.ID = "Create Request for <Type>"`.
   - It calls `busObj.BeforeCreate(PortalRequest)` so the object can queue any needed work.
4. Branch on whether `BeforeCreate` queued data-portal requests.
   - If `PortalRequest.RequestCount > 0`, the portal connects, processes the request batch, `busObj.AfterCreate(PortalRequest)` runs, and reader results are closed.
   - If `PortalRequest.RequestCount = 0`, the framework skips portal execution and calls `busObj.Create()` directly.
5. Finish the create lifecycle.
   - The portal disconnects in `Finally`.
   - After the `Try...Finally` block completes, `busObj.OnInstantiationComplete()` runs and the created object is returned.
6. Wrap any failure in a framework exception.
   - Exceptions are rethrown as `ApplicationException(MSG_DATA_CREATE_EX & ex.Message, ex)`.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([CreateObject called]) --> Check{Criteria supplied?}
	Check -->|No| EndErr([Throw SystemException])
	Check -->|Yes| NewObj[Instantiate target object]
	NewObj --> Before[Run BeforeCreate]
	Before --> Requests{Queued requests?}
	Requests -->|Yes| Portal[Connect portal and process request]
	Portal --> After[Run AfterCreate]
	Requests -->|No| Create[Call Create]
	After --> Done[Run OnInstantiationComplete]
	Create --> Done
	Done --> EndOk([Return created object])
```

## Failure and edge-case behavior

- A missing criteria object is rejected with `SystemException` before any object is instantiated, so no partially constructed business object is ever returned for that failure.
- `BeforeCreate` can choose a pure in-memory create by queuing no portal requests; the framework treats that as a valid, deliberate outcome and skips the portal entirely.
- Portal or hook failures are wrapped in `ApplicationException(MSG_DATA_CREATE_EX & ex.Message, ex)`, and the portal is always disconnected in `Finally` regardless of which branch failed.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb
