csla
csla copied to clipboard
Call data portal operation methods explicitly
Today, data portal operation methods are private and are called dynamically by the data portal. They are identified by attributes such as Fetch or Update.
This is a problem because AOT will optimize these methods out of the codebase. It is also a problem because Visual Studio grays out the code, thinking it is never invoked.
Using a code generator, it might be possible to explicitly invoke these methods. Here are my initial thoughts on how such a thing might work.
- A generator can look at the code and identify all data portal operation methods
- The generator can create an interface that includes all the methods, and code to implement the interface explicitly - invoking the actual methods
- The server-side data portal can be changed to detect this interface, and if it exists, to use the interface for invoking methods instead of invoking the private methods (which may provide slight performance improvement)
For example:
public partial class PersonEdit : BusinessBase<PersonEdit>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
public string Name
{
get => GetProperty(NameProperty);
set => SetProperty(NameProperty, value);
}
[Fetch]
private void Fetch(string name)
{
LoadProperty(NameProperty, name);
}
}
// generated code:
public interface IPersonEditOperations
{
void Fetch(string name);
}
public partial class PersonEdit : IPersonEditOperations
{
void IPersonEditOperations.Fetch(string name) => Fetch(name);
}
"and code to implement the interface implicitly" - I think you meant "explicitly".
What would be the trigger for the SG? The existence of the DP attribute(s) on the method within the type?
BTW you'd want to have a check to make sure the name you generate, IPersonEditOperations in this case, does not collide with an existing type name in scope. And I guarantee you'll need to do this, because someone, somewhere, has created a I{MyBOTypeName}Operations type in their code that'll break you ;).
First time I saw PersonEdit as partial class.
Is the explicit interface implementation only to make it look like the method is used?
Is the explicit interface implementation only to make it look like the method is used?
At a minimum, yes. This causes AOT and VS to think that the method is viable.
However, I am hopeful that we can go beyond this point and optimize the invocation of the operation methods by generating client-side extension methods that "know" which overload to invoke.
The idea goes like this:
- Generate a server-side interface where each method overload has a unique name, and delegates to the appropriate private operation method
- Generate client-side extension methods for
IDataPortal<T>with strongly-typed methods for each operation method - increasing quality of client-side code with typing (@StefanOssendorf has a generator that already does this) - On the client, each of those extension methods "knows" the overload that needs to be invoked, and so it can pass the unique name of the method on the interface to the server
- On the server, the data portal can use the unique operation method name from the client to invoke that method on the interface, which then invokes your private operation method
The only place reflection is needed would be step 4, and even there it would be a direct invocation instead of the overload scanning and scoring that exists currently.