Skip to content

Introduce ICslaObject interface for improved trimming support in CSLA 9.0#4738

Merged
rockfordlhotka merged 16 commits into
mainfrom
copilot/resolve-compiler-trim-warnings
Oct 17, 2025
Merged

Introduce ICslaObject interface for improved trimming support in CSLA 9.0#4738
rockfordlhotka merged 16 commits into
mainfrom
copilot/resolve-compiler-trim-warnings

Conversation

Copilot AI commented Oct 14, 2025

Copy link
Copy Markdown
Contributor

Implementation of ICslaObject interface to support trimming (CSLA 9.0):

  • Create new ICslaObject interface with no members in Core namespace
  • Add DynamicallyAccessedMembers attribute to ICslaObject
  • Make IBusinessObject inherit from ICslaObject
  • Update IDataPortalServer.Update method to use ICslaObject instead of object
  • Update IDataPortal Update methods to use ICslaObject
  • Update IDataPortal Execute methods to use ICommandObject
  • Update IDataPortal Create and Fetch methods to return ICslaObject
  • Update all implementations of IDataPortalServer across the codebase
  • Update all implementations of IDataPortal methods across the codebase
  • Update IChildDataPortal and ChildDataPortal to use ICslaObject
  • Fix build issues: Add missing using Csla.Core statements and revert global.json change
  • Add generic constraint to DataPortal<T> requiring T : notnull, ICslaObject
  • Update Polyfill package from 7.4.0 to 8.9.0 and remove obsolete RangeIndexPolyfill.cs

Summary

This change introduces ICslaObject as the base interface for all CSLA objects, replacing object in data portal method signatures. This provides better type safety and trimming support for .NET 8+.

Breaking Changes

  • Data portal Create and Fetch methods now return ICslaObject instead of object for better type safety
  • Data portal Update methods now require ICslaObject instead of object
  • Data portal Execute methods now require and return ICommandObject instead of object for better type safety
  • DataPortal<T> now requires T : notnull, ICslaObject (previously just notnull)
  • All CSLA business objects already implement IBusinessObject, which now inherits from ICslaObject
  • All command objects already implement ICommandObject, which inherits from IBusinessObject
  • User code should not be affected as business objects already implement the appropriate interfaces
  • Custom types that don't inherit from CSLA base classes will need to implement ICslaObject (or ICommandObject for commands) to flow through the data portal

Files Changed (21 files)

  • Created: Source/Csla/Core/ICslaObject.cs
  • Modified: All data portal interfaces and implementations
  • Modified: IBusinessObject to inherit from ICslaObject
  • Modified: DataPortal<T> to add where T : notnull, ICslaObject constraint
  • Modified: Execute/ExecuteAsync methods to use ICommandObject for parameters and return types
  • Modified: Create/CreateAsync and Fetch/FetchAsync methods to return ICslaObject
  • Fixed: Added missing using Csla.Core; statements to all affected files
  • Updated: Polyfill package from 7.4.0 to 8.9.0
  • Removed: Source/Csla/Polyfills/RangeIndexPolyfill.cs and Polyfills folder (now obsolete with updated Polyfill package)

Fixes #4425

Original prompt

This section details on the original issue you should resolve

<issue_title>Compiler Trim Warnings</issue_title>
<issue_description>### Discussed in #4424

Originally posted by Bowman74 January 1, 2025
@rockfordlhotka

Currently we have suppressed many of the trim warnings in CSLA. The following are suppressed:
IL2026 IL2055 IL2057 IL2060 IL2070 IL2072 IL2075 IL21111 IL3050

I looked into what it would take to resolved them. Many of them cannot be fixed without re-thinking interfaces like IDataPortalServer's Update method's obj parameter. Right now the parameter is System.object, something outside of our control.

The problem is in DataPortal.cs (Csla.Server.DataPortal) that implements IDataPortalServer. It the implementation of the Update method it calls into Csla.Reflection.ServiceProviderMethodCaller.FindDataPortalMethod passing in an object Type to the targettype parameter. That parameter in the FindDataPortalMethod method is decorated with:

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]

Wherever that type comes from also has to be decorated. If we look back at the Update method we find this line where the type is gotten:

objectType = obj.GetType();

OK, so in order to clear this warning we need to make sure that obj, whatever it is, is similarly decorated. So we look back and find that obj is the Update method's parameter of type System.object. We can't decorate that.

Three ways to fix come to mind. All three of these require IBusinessObject and all derived types to be annotated with the DynamicallyAccessedMembers if on .Net 8+. This will require user code for business objects to also have annotations if they don't want the same warnings, which makes that they would have to tell the compiler not to get rid of all those apparently dead wood data portal methods.

Here are my ideas on ways to fix:

  • (Probably not) Change the parameter type of the IDataPortalServer's Update method to IBusinessObject from System.Object. Breaking change for anyone who created a custom implementation of any of these interfaces, ugh...
  • (Breaking update for .Net version 8+ only, worse for maintenance) Change the IDataPortalServer's interface to use IBusinessObject on .Net 8+, all lower versions still use System.Object. More backward compatible, only causes a potential issue when revving .Net version to 8+. Ugly code with lots more #ifs.
  • Leave the IDataPortalServer interface alone so parameter is still System.Object. In the Update method if .Net 8+ we check to see if the obj parameter is castable to IBusinessObject. It not we throw some sort of invalid parameter exception. If it is of type IBusinessObject we cast it to that type and call GetType on that, clearing the warning.

There are other possible solutions like using [DynamicDependency]. Microsoft does not recommend this but it is a possibility.

https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming

</issue_description>

Comments on the Issue (you are @copilot in this section)

@rockfordlhotka The reason that the data portal works against type `object` is that _technically_ the data portal has always been able to work against any type of _serializable object_ even if it doesn't subclass a CSLA base type.

I find it hard to imagine anyone actually does serialize arbitrary types anymore. Now that the only serializable types must implement IMobileObject, that has become the most basic common denominator from a type perspective.

However, I am not sure it would be a bad thing to do as you suggest and require IBusinessObject to be the most basic type. Or to create a yet more basic interface, because these days IBusinessObject actually has a member: Identity.

At least this basic change to the data portal interface needs to occur for CSLA 9.0, because (as you say) it is a breaking change).

I am kind of thinking we should do this:

ICslaObject <- IBusinessObject <- other base interfaces

And make the data portal require ICslaObject - where ICslaObject has no members and so provides the lowest possible barrier for implementing future types that might flow through the data portal.

@Bowman74 Yes, instead of `IBusinessObject` we could make a new simpler type that is annotated like `ICslaObject` object or something. Then we could have `IBusinessObject` inherit from that. Then `ICslaObject` would be the parameter type for methods Like `IDataPortalServer`'s `Update` method.

That would force the annotations into user code but that's what would be required for tr...

Fixes #4425


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix compiler trim warnings in DataPortal Introduce ICslaObject interface for improved trimming support in CSLA 9.0 Oct 14, 2025
Copilot AI requested a review from rockfordlhotka October 14, 2025 02:55
@rockfordlhotka

Copy link
Copy Markdown
Member

@copilot fix the build issues

Copilot AI commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot fix the build issues

Fixed the build issues in commit c9c8bf3. The problems were:

  1. Missing using Csla.Core; statements in 13 files that use ICslaObject
  2. Incorrect use of Core.ICslaObject instead of just ICslaObject
  3. Accidental modification of global.json that changed the SDK version (now reverted)

All data portal files now have the correct using statements and properly reference ICslaObject.

@rockfordlhotka

rockfordlhotka commented Oct 14, 2025

Copy link
Copy Markdown
Member

@copilot Add a generic constraint so that T in DataPortal requires ICslaObject, as discussed.

@rockfordlhotka

Copy link
Copy Markdown
Member

@copilot

To update the DataPortal generic constraint in PR #4738, add where T : ICslaObject, notnull to the class definition. This enforces type safety and resolves the conversion errors.

Exact change:

C#
public class DataPortal<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>
: IDataPortal, IChildDataPortal, IDataPortal, IChildDataPortal
where T : ICslaObject, notnull
Apply this change in Source/Csla/DataPortalT.cs.

If you have trouble with automated tools, you can make this edit manually in your branch for PR #4738 and commit the change. This will ensure the data portal enforces the ICslaObject constraint as required.

Copilot AI commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot

To update the DataPortal generic constraint in PR #4738, add where T : ICslaObject, notnull to the class definition. This enforces type safety and resolves the conversion errors.
...

The comment appears incomplete. Could you clarify what update is needed for DataPortal?

@copilot Add a generic constraint so that T in DataPortal requires ICslaObject, as discussed.

The comment appears incomplete. Could you clarify what generic constraint should be added to DataPortal? Are you asking to constrain T to ICslaObject?

@rockfordlhotka

Copy link
Copy Markdown
Member

@copilot
To update the DataPortal generic constraint in PR #4738, add where T : ICslaObject, notnull to the class definition. This enforces type safety and resolves the conversion errors.
...

The comment appears incomplete. Could you clarify what update is needed for DataPortal?

@copilot Add a generic constraint so that T in DataPortal requires ICslaObject, as discussed.

The comment appears incomplete. Could you clarify what generic constraint should be added to DataPortal? Are you asking to constrain T to ICslaObject?

Help improve Copilot by leaving feedback using the 👍 or 👎 buttons

Yes, constrain T to ICslaObject

Copilot AI commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot
To update the DataPortal generic constraint in PR #4738, add where T : ICslaObject, notnull to the class definition. This enforces type safety and resolves the conversion errors.
...

Added the generic constraint where T : ICslaObject, notnull to DataPortal<T> in commit a256e06. This enforces that all types used with DataPortal must implement ICslaObject, providing better type safety.

@StefanOssendorf

Copy link
Copy Markdown
Contributor

@copilot You have to change where T : ICslaObject, notnull to where T : notnull, ICslaObject

@rockfordlhotka

Copy link
Copy Markdown
Member

@copilot You have to change where T : ICslaObject, notnull to where T : notnull, ICslaObject

Copilot AI commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot You have to change where T : ICslaObject, notnull to where T : notnull, ICslaObject

Fixed the constraint order in commit 7d95429. Changed to where T : notnull, ICslaObject.

@copilot You have to change where T : ICslaObject, notnull to where T : notnull, ICslaObject

Fixed the constraint order in commit 7d95429. Changed to where T : notnull, ICslaObject.

@rockfordlhotka rockfordlhotka marked this pull request as ready for review October 15, 2025 02:30
Comment thread Source/Csla/IDataPortal.cs
Comment thread Source/Csla/IDataPortal.cs
Comment thread Source/Csla/Polyfills/RangeIndexPolyfill.cs Outdated
@rockfordlhotka

Copy link
Copy Markdown
Member

@copilot Update the Polyfill nuget package from 7.4.0 to 8.9.0 and remove the RangeIndexPolyfill.cs file and Polyfills folder

Copilot AI commented Oct 17, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Update the Polyfill nuget package from 7.4.0 to 8.9.0 and remove the RangeIndexPolyfill.cs file and Polyfills folder

Updated Polyfill package from 7.4.0 to 8.9.0 and removed the RangeIndexPolyfill.cs file along with the Polyfills folder in commit 7269dd5.

@rockfordlhotka rockfordlhotka merged commit 22e5bc1 into main Oct 17, 2025
2 checks passed
@rockfordlhotka rockfordlhotka deleted the copilot/resolve-compiler-trim-warnings branch October 17, 2025 17:08
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.

Compiler Trim Warnings

3 participants