Ossendorf.Csla.DataPortalExtensionGenerator 1.0.0

dotnet add package Ossendorf.Csla.DataPortalExtensionGenerator --version 1.0.0                
NuGet\Install-Package Ossendorf.Csla.DataPortalExtensionGenerator -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ossendorf.Csla.DataPortalExtensionGenerator" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Ossendorf.Csla.DataPortalExtensionGenerator --version 1.0.0                
#r "nuget: Ossendorf.Csla.DataPortalExtensionGenerator, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Ossendorf.Csla.DataPortalExtensionGenerator as a Cake Addin
#addin nuget:?package=Ossendorf.Csla.DataPortalExtensionGenerator&version=1.0.0

// Install Ossendorf.Csla.DataPortalExtensionGenerator as a Cake Tool
#tool nuget:?package=Ossendorf.Csla.DataPortalExtensionGenerator&version=1.0.0                

DataPortal extensions for CSLA.NET

NuGet Version Generator GitHub Release
NuGet Version Analyzer_

PullRequest Validation

A Source Generator package that generates extension methods for IDataPortal<T> and IChildDataPortal<T>.
The extension methods are derived from annotated methods of business objects using CSLA.NET attributes like Fetch, Create, ....

How to install

dotnet add package Ossendorf.Csla.DataPortalExtensionsGenerator
<PackageReference Include="Ossendorf.Csla.DataPortalExtensionsGenerator" Version="0.4.0-preview1" PrivateAssets="all" ExcludeAssets="runtime" />

Either way adds the source generator to your project. Make sure to add PrivateAssets="all" ExcludeAssets="runtime" to mark it as a build dependency. Otherwise it flows to projects which depend on your project.

To use the generator, add the [Ossendorf.Csla.DataPortalExtensionsGenerator.DataPortalExtensions] attribute to a class which should containt the extensions.
For example:

[Ossendorf.Csla.DataPortalExtensionsGenerator.DataPortalExtensions]
public static partial class DataPortalExtensions {
}

Your business object:

namespace MyNamespace;

public class Address : BusinessBase<Address> {
    [Create]
    private void CreateLocally() {
        // creation logic
    }

    [Fetch]
    private async Task ById(Guid id) {
        // fetch logic
    }

    [Fetch]
    private async Task Fetch(string foo) {
        // fetch logic
    }
}

This will generate the following code:

static partial class DataPortalExtensions {
    public static global::System.Threading.Tasks.Task<global::MyNamespace.Address> CreateLocally(this global::Csla.IDataPortal<global::MyNamespace.Address> portal) => portal.CreateAsync();
    public static global::System.Threading.Tasks.Task<global::MyNamespace.Address> ById(this global::Csla.IDataPortal<global::MyNamespace.Address> portal, global::System.Guid id) => portal.FetchAsync(id);
    public static global::System.Threading.Tasks.Task<global::MyNamespace.Address> Fetch(this global::Csla.IDataPortal<global::MyNamespace.Address> portal, string foo) => portal.FetchAsync(foo);
}

[!WARNING]
In the example above the last extension methods has the name Fetch which is already defined by the IDataPortal interface. That means the extension method is never used, because the compiler resolves the instance method and not the extension method to be used.
To avoid that use the configuration explained next.

How to configure the generator

You can configure the following for the generator to respect

  • method prefix (default = "")
  • method suffix (default = "")
  • Enable/Disable nullable annotation context (default = Enable)
  • SuppressWarningCS8669 (default = false)

The fetch named method example from above can be resolved with a prefix/suffix to generate a method with the name YourFetch which in turn can be used and provides reliable compiler support.

You can add the following properties to your csproj-file to configure the generator.

<PropertyGroup>
    <DataPortalExtensionGen_MethodPrefix>Prefix</DataPortalExtensionGen_MethodPrefix>
    <DataPortalExtensionGen_MethodSuffix>Suffix</DataPortalExtensionGen_MethodSuffix>
    <DataPortalExtensionGen_NullableContext>Enable/Disable</DataPortalExtensionGen_NullableContext>
    <DataPortalExtensionGen_SuppressWarningCS8669>true/false</DataPortalExtensionGen_SuppressWarningCS8669>
</PropertyGroup>

With this added the consuming project the generator picks the values up and adds them as prefix or suffix.

[!TIP] To avoid wrong method resolution when your CSLA methods have the same name as the operation they perform. E.g. the method name is Fetch() for the [Fetch] attribute. Use either the prefix or suffix configuration to make them different from the methods provided from IDataPortal.

Raodmap

  • Special case commands to an extension like commandPortal.ExecuteCommand(<params>) which combines Create+Execute.
  • Support for generic business objects
  • Add attribute to exclude methods explicitly

A lot of implementation details are derived/taken from the great series Andrew Lock: Creating a source generator. If you want to create your own source generator I can recommend that series wholeheartedly.

Why isn't this generator adding the Async suffix for it's generated methods?

First of all in the current day nearly everything is async by default and not exception. That mean's I'm expecting that the data portals are used over some kind of wire which is async in nature. So since I don't want to support sync-methods (currently, maybe someone wants them badly?) and I only have async methods why should I add noise to the method name? A great post which explains the point in great detail is No Async Suffix - NServiceBus.
If you want the suffix for your code, just add it via the prefix configuration property 😃.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 734 10/7/2024
0.5.0-preview1 2,624 3/31/2024
0.4.1-preview1 141 3/1/2024
0.4.0-preview1 93 2/27/2024 0.4.0-preview1 is deprecated because it has critical bugs.
0.3.0-preview3 353 2/25/2024
0.3.0-preview2 73 2/25/2024
0.2.0-preview1.9 52 2/25/2024
0.2.0-preview1 100 2/22/2024
0.1.0-preview2 76 2/21/2024
0.1.0-preview1 86 2/11/2024
0.0.1-alpha4.7 69 2/10/2024
0.0.1-alpha4.6 59 2/10/2024
0.0.1-alpha4.3 57 2/10/2024