Introduce ICslaObject interface for improved trimming support in CSLA 9.0#4738
Conversation
Co-authored-by: rockfordlhotka <[email protected]>
Co-authored-by: rockfordlhotka <[email protected]>
Co-authored-by: rockfordlhotka <[email protected]>
|
@copilot fix the build issues |
Co-authored-by: rockfordlhotka <[email protected]>
Fixed the build issues in commit c9c8bf3. The problems were:
All data portal files now have the correct using statements and properly reference |
|
@copilot Add a generic constraint so that T in DataPortal requires ICslaObject, as discussed. |
|
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# 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. |
The comment appears incomplete. Could you clarify what update is needed for DataPortal?
The comment appears incomplete. Could you clarify what generic constraint should be added to DataPortal? Are you asking to constrain T to ICslaObject? |
Yes, constrain T to ICslaObject |
Co-authored-by: rockfordlhotka <[email protected]>
Added the generic constraint |
|
@copilot You have to change |
|
@copilot You have to change |
Co-authored-by: rockfordlhotka <[email protected]>
Fixed the constraint order in commit 7d95429. Changed to
Fixed the constraint order in commit 7d95429. Changed to |
|
@copilot Update the Polyfill nuget package from 7.4.0 to 8.9.0 and remove the RangeIndexPolyfill.cs file and Polyfills folder |
…fill.cs Co-authored-by: rockfordlhotka <[email protected]>
… of ICslaObject Co-authored-by: rockfordlhotka <[email protected]>
Implementation of ICslaObject interface to support trimming (CSLA 9.0):
Summary
This change introduces
ICslaObjectas the base interface for all CSLA objects, replacingobjectin data portal method signatures. This provides better type safety and trimming support for .NET 8+.Breaking Changes
ICslaObjectinstead ofobjectfor better type safetyICslaObjectinstead ofobjectICommandObjectinstead ofobjectfor better type safetyT : notnull, ICslaObject(previously justnotnull)IBusinessObject, which now inherits fromICslaObjectICommandObject, which inherits fromIBusinessObjectICslaObject(orICommandObjectfor commands) to flow through the data portalFiles Changed (21 files)
Source/Csla/Core/ICslaObject.csIBusinessObjectto inherit fromICslaObjectDataPortal<T>to addwhere T : notnull, ICslaObjectconstraintICommandObjectfor parameters and return typesICslaObjectusing Csla.Core;statements to all affected filesSource/Csla/Polyfills/RangeIndexPolyfill.csand 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 IL3050I looked into what it would take to resolved them. Many of them cannot be fixed without re-thinking interfaces like
IDataPortalServer'sUpdatemethod's obj parameter. Right now the parameter isSystem.object, something outside of our control.The problem is in DataPortal.cs (Csla.Server.DataPortal) that implements
IDataPortalServer. It the implementation of theUpdatemethod it calls intoCsla.Reflection.ServiceProviderMethodCaller.FindDataPortalMethodpassing in an objectTypeto the targettype parameter. That parameter in theFindDataPortalMethodmethod 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
Updatemethod's parameter of typeSystem.object. We can't decorate that.Three ways to fix come to mind. All three of these require
IBusinessObjectand all derived types to be annotated with theDynamicallyAccessedMembersif 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:
IDataPortalServer'sUpdate method toIBusinessObjectfromSystem.Object. Breaking change for anyone who created a custom implementation of any of these interfaces, ugh...IDataPortalServer's interface to useIBusinessObjecton .Net 8+, all lower versions still useSystem.Object. More backward compatible, only causes a potential issue when revving .Net version to 8+. Ugly code with lots more #ifs.IDataPortalServerinterface alone so parameter is stillSystem.Object. In the Update method if .Net 8+ we check to see if the obj parameter is castable toIBusinessObject. It not we throw some sort of invalid parameter exception. If it is of typeIBusinessObjectwe cast it to that type and callGetTypeon 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
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
IBusinessObjectto be the most basic type. Or to create a yet more basic interface, because these daysIBusinessObjectactually 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 interfacesAnd make the data portal require
@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.ICslaObject- whereICslaObjecthas no members and so provides the lowest possible barrier for implementing future types that might flow through the data portal.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.