Skip to content

Remove legacy data portal operation method name support - #4943

Open
rockfordlhotka wants to merge 5 commits into
mainfrom
issue-4828/remove-legacy-operation-methods
Open

rockfordlhotka wants to merge 5 commits into
mainfrom
issue-4828/remove-legacy-operation-methods

Conversation

@rockfordlhotka

@rockfordlhotka rockfordlhotka commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Closes #4828

CSLA 11 removes the data portal's fallback of finding operation methods by name (DataPortal_Fetch, Child_Update, and so on). Only methods with an operation attribute are invoked. Matching by name has caused real bugs, such as #4595, where an unrelated DataPortal_Execute was called.

Runtime

  • ServiceProviderMethodCaller: removed the name-based fallback and the |nolegacy cache key. DataPortalOptions.UseLegacyOperationMethods is removed.
  • Default child create: the protected virtual Child_Create() on BusinessBase (which calls CheckRules()), BusinessListBase, and BusinessBindingListBase is now marked [CreateChild]. The name is unchanged, so existing overrides still compile and inherit the attribute. A class's own [CreateChild] method still wins, because it's declared on a more-derived type.
  • "Not supported" stubs: the private DataPortal_XYZ methods that threw NotSupportedException are deleted from CommandBase, ReadOnlyBase, ReadOnlyListBase, ReadOnlyBindingListBase, NameValueListBase, DynamicListBase, and DynamicBindingListBase. Unsupported calls now get the normal "method not found" error.
  • ObjectFactory child create: no longer looks for a method named Child_Create on the factory, then the business type. It uses the business type's [CreateChild] method. The child data portal always invokes the method on the business object, so a method found on the factory was never the right target anyway.
  • Sync Child_Update(params object[]) on the list and document base classes is unchanged. It's an ordinary protected helper for sync [Update] methods, and only Child_UpdateAsync is an operation. I tried [Obsolete] and reverted it: sync root lists have no non-obsolete alternative, because a sync Save() can't reach an async operation method in local mode.

Analyzers

  • A method counts as a data portal operation only by attribute, so CSLA0002, 0009, 0010, 0012, 0013, and 0019 ignore attribute-less legacy names.
  • CSLA0014 still finds legacy-named methods without an attribute. It is now a Warning, with a new message, and keeps its add-attribute code fix. It skips overrides of attributed base methods such as Child_Create.

Tests and docs

  • Added operation attributes to about 94 legacy-named test methods. Replaced the legacy-fallback tests with "not found" tests. Added tests for the default and ObjectFactory child create lookup. Updated the analyzer tests.
  • New docs/Upgrading to CSLA 11.md, a CSLA 11 entry in releasenotes.md, updated analyzer docs, and XML doc comments that no longer refer to DataPortal_XYZ names.

Verification

  • dotnet build Source/csla.test.sln: 0 errors and no new warnings.
  • dotnet test Source/csla.test.sln (CI filter and settings): all pass on net10.0 and net11.0, plus net462 for GraphMerger.
  • MAUI was not built locally. Source/Csla.Analyzers.sln doesn't build on main, because it references Csla.Analyzers/Csla.Analyzers.Tests/Csla.Analyzers.Tests.csproj, which moved to Source/tests. That's not caused by this PR. The analyzer tests run through csla.test.sln.

Notes for review

  • Overlap with Call data portal operation methods explicitly via bundled source generators #4925 (explicit operation calls through generators, still open): textual conflicts in the base class declarations and the analyzer release and resource files. Because the base Child_Create methods now have [CreateChild], Call data portal operation methods explicitly via bundled source generators #4925's generator will emit dispatch for them in Csla.dll. Whichever PR merges second should check that output.
  • A legacy-named method without an attribute isn't always a runtime error. When the base class has its own operation, it runs instead (for example, an attribute-less Child_Create() gets the base one). The upgrade guide calls this out and points to CSLA0014.
  • Source/tests/Csla.Analyzers.IntegrationTests isn't in any solution and was left as is.

🤖 Generated with Claude Code

rockfordlhotka and others added 5 commits October 8, 2026 17:21
- Remove the DataPortal_XYZ/Child_XYZ name-matching fallback from
  ServiceProviderMethodCaller and the DataPortalOptions.UseLegacyOperationMethods option
- Add operation attributes to legacy-named test operation methods
- Replace the legacy fallback tests with tests that attribute-less
  legacy-named methods are not found
- Draft release notes, upgrade guide, and analyzer doc updates

Base class changes (Phase 2) and analyzer changes (Phase 3) follow after #4925.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- D1: delete the private "not supported" DataPortal_XYZ stubs from
  CommandBase, ReadOnlyBase, ReadOnlyListBase, ReadOnlyBindingListBase,
  NameValueListBase, DynamicListBase, and DynamicBindingListBase
- D2: mark the default Child_Create methods on BusinessBase,
  BusinessListBase, and BusinessBindingListBase with [CreateChild]
- D3: child create with an ObjectFactory no longer looks for a method
  named Child_Create; it uses the [CreateChild] method on the business type
- D4: leave the sync Child_Update helpers as ordinary protected methods
  that sync [Update] methods can call; only Child_UpdateAsync is an operation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A method qualifies as a data portal operation only when it has an
  operation attribute, so the operation analyzers (CSLA0002, 0009, 0010,
  0012, 0013, 0019) no longer act on attribute-less DataPortal_XYZ and
  Child_XYZ names
- CSLA0014 still finds legacy-named methods without an attribute, is now
  a Warning (the data portal never calls them), and skips overrides of
  attributed base methods such as BusinessBase.Child_Create
- Update the analyzer tests for attribute-only detection

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-only operations

- XML doc comments on CommandBase, Core.BusinessBase, DynamicListBase,
  DynamicBindingListBase, IDataPortal, and IDataPortalT refer to
  operation attributes instead of DataPortal_XYZ method names
- Upgrade guide and release notes describe the base class changes
  (default Child_Create, removed "not supported" stubs, ObjectFactory
  child create, sync Child_Update) and when a legacy-named method is
  silently skipped rather than failing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ypes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Inherited operation attributes are not recognized by most analyzers, causing diagnostics such as CSLA0013 to regress.

2 open findings
What changed in this PR

Removes legacy name-based data portal dispatch in favor of operation attributes.

Changes:

  • Removes runtime fallback and legacy configuration.
  • Updates analyzers, base child creation, and tests.
  • Adds migration and release documentation.
File Description
Source/​tests/​Csla.Web.Mvc.Test/​ModelBinderTest/​SingleRoot.cs Adds operation attributes.
Source/​tests/​Csla.Web.Mvc.Test/​ModelBinderTest/​RootWithValidation.cs Marks create operation.
Source/​tests/​Csla.Web.Mvc.Test/​ModelBinderTest/​RootWithChildren.cs Marks fetch operations.
Source/​tests/​Csla.Web.Mvc.Test/​ModelBinderTest/​RootList.cs Marks fetch operation.
Source/​tests/​Csla.Web.Mvc.Test/​ModelBinderTest/​Child.cs Marks child fetch.
Source/​tests/​Csla.test/​ValidationRules/​RuleBaseClassesRoot.cs Marks create operation.
Source/​tests/​Csla.test/​ValidationRules/​HasRulesManager2.partial.cs Marks fetch operation.
Source/​tests/​Csla.test/​RollBack/​RollbackRoot.cs Marks create and fetch operations.
Source/​tests/​Csla.test/​Nullable/​NullableObject.cs Marks fetch operation.
Source/​tests/​Csla.test/​Linq/​LinqObservableCollectionTest.cs Marks child fetch.
Source/​tests/​Csla.test/​IO/​DPMethodOverloadTests.cs Marks fetch overloads.
Source/​tests/​Csla.test/​GraphMergeAsync/​TestClasses.cs Marks create operations.
Source/​tests/​Csla.test/​GraphMerge/​TestClasses.cs Marks create operations.
Source/​tests/​Csla.test/​FieldManager/​ChildList.cs Marks child update.
Source/​tests/​Csla.test/​FieldManager/​Child.cs Marks child create.
Source/​tests/​Csla.test/​Fakes/​Server/​ReadOnlyTests/​ReadOnlyPersonList.cs Marks fetch operation.
Source/​tests/​Csla.test/​Fakes/​Server/​ReadOnlyTests/​ReadOnlyPerson.partial.cs Marks fetch operation.
Source/​tests/​Csla.test/​Fakes/​Server/​DataPortal/​TestBO.cs Marks fetch overloads.
Source/​tests/​Csla.test/​Fakes/​Server/​DataPortal/​Single.cs Marks create and fetch operations.
Source/​tests/​Csla.test/​Fakes/​Server/​DataPortal/​PrimitiveCriteriaSingle.cs Marks criteria operations.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​CustomerWithErrorList.cs Marks fetch operation.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​CustomerWithError.cs Marks fetch and create operations.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​CustomerList.cs Marks fetch operation.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​CustomerContactList.cs Marks child fetch.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​CustomerContact.cs Marks child operations.
Source/​tests/​Csla.test/​Fakes/​Server/​CslaDataProvider/​Customer.cs Marks root operations.
Source/​tests/​Csla.test/​DataPortal/​TransactionalRoot.cs Marks fetch operation.
Source/​tests/​Csla.test/​DataPortal/​StronglyTypedDP.cs Marks create and fetch operations.
Source/​tests/​Csla.test/​DataPortal/​SplitOverloadBase.cs Marks fetch overloads.
Source/​tests/​Csla.test/​DataPortal/​SplitBase.cs Marks fetch operation.
Source/​tests/​Csla.test/​DataPortal/​SingleOverload.cs Marks fetch overloads.
Source/​tests/​Csla.test/​DataPortal/​LegacySplitBase.cs Marks fetch operation.
Source/​tests/​Csla.test/​DataPortal/​Legacy.cs Marks fetch operation.
Source/​tests/​Csla.test/​DataPortal/​InterceptorTests.cs Marks intercepted operations.
Source/​tests/​Csla.test/​DataPortal/​DpRoot.cs Marks create and fetch operations.
Source/​tests/​Csla.test/​DataPortal/​DataPortalTests.cs Marks fetch operation.
Source/​tests/​Csla.test/​ChildChanged/​OptimizeChildChangedTests.cs Marks root and child fetches.
Source/​tests/​Csla.test/​BasicModern/​Root.cs Marks fetch operation.
Source/​tests/​Csla.test/​BasicModern/​Child.cs Marks all child operations.
Source/​tests/​Csla.test/​Basic/​ReadOnlyList.cs Marks fetch operation.
Source/​tests/​Csla.test/​Basic/​NameValueListObj.cs Marks fetch operation.
Source/​tests/​Csla.test/​Basic/​GenRootBase.cs Marks create and fetch operations.
Source/​tests/​Csla.test/​Basic/​CollectionTests.cs Marks fetch operation.
Source/​tests/​Csla.test/​AppContext/​SimpleRoot.cs Marks create and fetch operations.
Source/​tests/​csla.netcore.test/​DataPortal/​ServiceProviderMethodCallerTests.cs Replaces legacy fallback tests.
Source/​tests/​csla.netcore.test/​DataPortal/​InheritedOperationTests.cs Marks inherited operations.
Source/​tests/​Csla.Ios.Test/​Nullable/​NullableEntity.cs Marks create operation.
Source/​tests/​Csla.Analyzers.Tests/​Extensions/​IMethodSymbolExtensionsTests.cs Verifies attribute-only qualification.
Source/​tests/​Csla.Analyzers.Tests/​Extensions/​DataPortalOperationQualificationTests.cs Updates qualification behavior.
Source/​tests/​Csla.Analyzers.Tests/​DoesOperationHaveAttributeAnalyzerTests.cs Tests warning and overrides.
Source/​Csla/​Reflection/​ServiceProviderMethodCaller.cs Removes name-based lookup.
Source/​Csla/​ReadOnlyListBase.cs Removes unsupported-operation stubs.
Source/​Csla/​ReadOnlyBindingListBase.cs Removes unsupported-operation stubs.
Source/​Csla/​ReadOnlyBase.cs Removes unsupported-operation stubs.
Source/​Csla/​NameValueListBase.cs Removes unsupported-operation stubs.
Source/​Csla/​IDataPortalT.cs Updates execute documentation.
Source/​Csla/​IDataPortal.cs Updates execute documentation.
Source/​Csla/​DynamicListBase.cs Updates documentation and removes stubs.
Source/​Csla/​DynamicBindingListBase.cs Updates documentation and removes stubs.
Source/​Csla/​Core/​BusinessBase.cs Adds default attributed child create.
Source/​Csla/​Configuration/​Fluent/​DataPortalOptions.cs Removes legacy option.
Source/​Csla/​CommandBase.cs Removes legacy stubs and updates docs.
Source/​Csla/​BusinessListBase.cs Attributes default child create.
Source/​Csla/​BusinessBindingListBase.cs Attributes default child create.
Source/​Csla.Analyzers/​Csla.Analyzers/​Properties/​Resources.resx Updates analyzer warning text.
Source/​Csla.Analyzers/​Csla.Analyzers/​Extensions/​DataPortalOperationQualification.cs Makes qualification attribute-only.
Source/​Csla.Analyzers/​Csla.Analyzers/​DoesOperationHaveAttributeAnalyzer.cs Warns for missing attributes.
Source/​Csla.Analyzers/​Csla.Analyzers/​AnalyzerReleases.Unshipped.md Records severity change.
releasenotes.md Documents the breaking change.
docs/​Upgrading to CSLA 11.md Adds migration guidance.
docs/​Data-Access.md Replaces legacy terminology.
docs/​analyzers/​CSLA0014-DoesOperationHaveAttributeAnalyzer.md Documents new warning behavior.
docs/​analyzers/​CSLA0013-DoesChildOperationHaveRunLocalAnalyzer.md Updates attributed example.
docs/​analyzers/​CSLA0012-FindOperationsWithIncorrectReturnTypesAnalyzer.md Updates attributed example.
docs/​analyzers/​CSLA0010-FindOperationsWithNonSerializableArgumentsAnalyzer.md Updates attributed example.
docs/​analyzers/​CSLA0009-IsOperationMethodPublicAnalyzer.md Updates attributed example.
docs/​analyzers/​CSLA0002-IsOperationMethodPublicAnalyzer.md Updates attributed example.
docs/​Abstractions-in-CSLA.md Modernizes create-operation example.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

/// </summary>
public static implicit operator bool(DataPortalOperationQualification qualification) =>
qualification.ByAttribute | qualification.ByNamingConvention;
qualification.ByAttribute;
Comment on lines +31 to +32
/// and a method marked with the <see cref="FetchAttribute"/>
/// to implement data retrieval.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove all legacy data portal operation method support

2 participants