Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ permissions:
id-token: write

env:
DOTNET_VERSION: '10.0.x'
DOTNET_VERSION: '11.0.x'
SOLUTION_FILE: 'src/CloudNimble.EasyAF.slnx'

jobs:
Expand Down Expand Up @@ -72,17 +72,19 @@ jobs:
shell: pwsh
run: |
Write-Host "Installing .NET versions..."
$versions = @("8.0", "9.0", "10.0")
foreach ($version in $versions) {
Write-Host "Installing .NET $version..."
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
$installDir = "$env:ProgramFiles\dotnet"

foreach ($channel in @("8.0", "9.0", "10.0")) {
Write-Host "Installing .NET $channel..."
./dotnet-install.ps1 -Channel $channel -InstallDir $installDir
}

# Add to PATH for this job
echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# 11.0.1xx is the SDK feature band that contains 11.0.100-rc.1
Write-Host "Installing .NET 11.0.1xx (preview/RC)..."
./dotnet-install.ps1 -Channel 11.0.1xx -Quality preview -InstallDir $installDir

# Verify installation
echo $installDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
dotnet --list-sdks

- name: Get version variables
Expand Down Expand Up @@ -182,6 +184,16 @@ jobs:
- name: Checkout code
uses: actions/checkout@v5

- name: Install .NET SDK
shell: pwsh
run: |
# Checkout brings global.json, so `dotnet nuget push` needs the 11.0.1xx SDK.
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
$installDir = "$env:ProgramFiles\dotnet"
./dotnet-install.ps1 -Channel 11.0.1xx -Quality preview -InstallDir $installDir
echo $installDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
dotnet --list-sdks

- name: Download artifacts
uses: actions/download-artifact@v8
with:
Expand Down
20 changes: 11 additions & 9 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ permissions:
actions: write

env:
DOTNET_VERSION: '10.0.x'
DOTNET_VERSION: '11.0.x'
SOLUTION_FILE: 'src/CloudNimble.EasyAF.slnx'

jobs:
Expand Down Expand Up @@ -60,17 +60,19 @@ jobs:
shell: pwsh
run: |
Write-Host "Installing .NET versions..."
$versions = @("8.0", "9.0", "10.0")
foreach ($version in $versions) {
Write-Host "Installing .NET $version..."
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
$installDir = "$env:ProgramFiles\dotnet"

foreach ($channel in @("8.0", "9.0", "10.0")) {
Write-Host "Installing .NET $channel..."
./dotnet-install.ps1 -Channel $channel -InstallDir $installDir
}

# Add to PATH for this job
echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# 11.0.1xx is the SDK feature band that contains 11.0.100-rc.1
Write-Host "Installing .NET 11.0.1xx (preview/RC)..."
./dotnet-install.ps1 -Channel 11.0.1xx -Quality preview -InstallDir $installDir

# Verify installation
echo $installDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
dotnet --list-sdks

- name: Get version variables
Expand Down
5 changes: 5 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"sdk": {
"version": "11.0.100-rc.1.26425.128",
"rollForward": "latestFeature",
"allowPrerelease": true
},
"test": {
"runner": "Microsoft.Testing.Platform"
}
Expand Down
29 changes: 28 additions & 1 deletion src/CloudNimble.EasyAF.Analyzers.EF6/readme.md
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
# EasyAF Analyzers & Generators
# EasyAF.Analyzers.EF6

Roslyn source generators for EasyAF EF6 models (entities, DbContext, managers, Restier APIs).

## Install

```bash
dotnet add package EasyAF.Analyzers.EF6
```

The package ships as an analyzer. Adding the reference is enough; you do not call the generators from application code.

## Usage

Point the generator at your EDMX (via the EasyAF MSBuild props the package imports) and rebuild. Generated C# is written as analyzer output.

Prefer `dotnet easyaf code generate` when you want files on disk instead of compiler-generated sources.

Requires an EF6 EDMX in the consuming project. For EF Core, generate EDMX with `EasyAF.EFCoreToEdmx` first.

## Documentation

- Docs: https://easyaf.dev
- Source: https://github.com/CloudNimble/EasyAF

## License

MIT © CloudNimble, Inc.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0;</TargetFrameworks>
<TargetFrameworks>net11.0;net10.0;net9.0;net8.0;</TargetFrameworks>
<DocumentationFile>$(DocumentationFile)\$(AssemblyName).xml</DocumentationFile>
<DefineConstants>EFCORE</DefineConstants>
</PropertyGroup>
Expand All @@ -11,37 +11,43 @@
<PackageReference Include="SimpleMessageBus.Publish" Version="[6.*-*, 7.0.0)" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net11.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[11.*-*, 12.0.0)" />
<PackageReference Include="System.Text.Json" Version="[11.*-*, 12.0.0)" />
<!-- Plus has no 11.x package yet. -->
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[10.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[10.*, 11.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[10.*, 11.0.0)" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[10.*, 12.0.0)" />
<PackageReference Include="System.Text.Json" Version="[10.*, 12.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[10.*, 12.0.0)" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[9.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[9.*, 11.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[9.*, 11.0.0)" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[9.*, 12.0.0)" />
<PackageReference Include="System.Text.Json" Version="[9.*, 12.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[9.*, 12.0.0)" />

<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[9.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[9.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[8.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[8.*, 11.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[8.*, 11.0.0)" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[8.*, 12.0.0)" />
<PackageReference Include="System.Text.Json" Version="[8.*, 12.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[8.*, 12.0.0)" />

<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[8.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[8.*, 11.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[8.*, 11.0.0)" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="[8.*, 12.0.0)" />
<PackageReference Include="System.Text.Json" Version="[8.*, 12.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="[8.*, 12.0.0)" />

<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
Expand Down
40 changes: 40 additions & 0 deletions src/CloudNimble.EasyAF.Business.EFCore/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# EasyAF.Business.EFCore

Entity managers for Entity Framework Core: CRUD, audit fields, and lifecycle hooks.

## Install

```bash
dotnet add package EasyAF.Business.EFCore
```

## Usage

```csharp
public class UserManager : EntityManager<MyDbContext, User>
{
public UserManager(MyDbContext context, IMessagePublisher publisher)
: base(context, publisher) { }

public override async Task OnInsertingAsync(User entity)
{
await base.OnInsertingAsync(entity); // audit fields
entity.IsActive = true;
}
}
```

Also includes `IdentifiableEntityManager`, `StatusEntityManager`, and `StateMachineEntityManager`. For EF6, use `EasyAF.Business.EF6`.

On .NET 11, `DirectUpdate` / `DirectDelete` are stubbed until Z.EntityFramework.Plus ships an EF Core 11 package.

Requires `EasyAF.Data.EFCore`.

## Documentation

- Docs: https://easyaf.dev/guides/business-layer
- Source: https://github.com/CloudNimble/EasyAF

## License

MIT © CloudNimble, Inc.
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net10.0;net9.0;net8.0;</TargetFrameworks>
<TargetFrameworks>net11.0;net10.0;net9.0;net8.0;</TargetFrameworks>
<DocumentationFile>$(DocumentationFile)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Ben.TypeDictionary" Version="[*, 2.0.0)" />
<PackageReference Include="EntityFramework" Version="6.*" />
<PackageReference Include="SimpleMessageBus.Publish" Version="[6.*-*, 7.0.0)" />
<PackageReference Include="Z.EntityFramework.Plus.EF6" Version="9.*" />
<PackageReference Include="Z.EntityFramework.Plus.EF6" Version="10.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net11.0'">
<PackageReference Include="System.Text.Json" Version="[11.*-*, 12.0.0)" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[11.*-*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="System.Text.Json" Version="[10.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[10.*, 12.0.0)" />
<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[10.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[10.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="System.Text.Json" Version="[9.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[9.*, 12.0.0)" />
<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[9.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[9.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" Version="[8.*, 11.0.0)" />
<PackageReference Include="System.Text.Json" Version="[8.*, 12.0.0)" />
<!-- Dealing with security vulnerabilities -->
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 11.0.0)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="[8.*, 12.0.0)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
Expand Down
20 changes: 20 additions & 0 deletions src/CloudNimble.EasyAF.Business/EntityManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,12 @@ public async Task<int> DirectUpdateAsync(Expression<Func<TEntity, bool>> predica
{
Ensure.ArgumentNotNull(predicate, nameof(predicate));

#if NET11_0 && EFCORE
Console.WriteLine("DirectUpdateAsync is not currently available on .NET 11.");
return await Task.FromResult(0).ConfigureAwait(false);
#else
return await DataContext.Set<TEntity>().Where(predicate).UpdateFromQueryAsync(updateExpression).ConfigureAwait(false);
#endif
}

/// <summary>
Expand All @@ -476,7 +481,12 @@ public int DirectUpdate(Expression<Func<TEntity, bool>> predicate, Expression<Fu
{
Ensure.ArgumentNotNull(predicate, nameof(predicate));

#if NET11_0 && EFCORE
Console.WriteLine("DirectUpdate is not currently available on .NET 11.");
return 0;
#else
return DataContext.Set<TEntity>().Where(predicate).UpdateFromQuery(updateExpression);
#endif
}

#endregion
Expand Down Expand Up @@ -566,7 +576,12 @@ public async Task<int> DirectDeleteAsync(Expression<Func<TEntity,bool>> predicat
{
Ensure.ArgumentNotNull(predicate, nameof(predicate));

#if NET11_0 && EFCORE
Console.WriteLine("DirectDeleteAsync is not currently available on .NET 11.");
return await Task.FromResult(0).ConfigureAwait(false);
#else
return await DataContext.Set<TEntity>().Where(predicate).DeleteFromQueryAsync().ConfigureAwait(false);
#endif
}

/// <summary>
Expand All @@ -582,7 +597,12 @@ public int DirectDelete(Expression<Func<TEntity,bool>> predicate)
{
Ensure.ArgumentNotNull(predicate, nameof(predicate));

#if NET11_0 && EFCORE
Console.WriteLine("DirectDelete is not currently available on .NET 11.");
return 0;
#else
return DataContext.Set<TEntity>().Where(predicate).DeleteFromQuery();
#endif
}

#endregion
Expand Down
38 changes: 38 additions & 0 deletions src/CloudNimble.EasyAF.Business/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# EasyAF.Business.EF6

Entity managers for Entity Framework 6: CRUD, audit fields, and lifecycle hooks.

## Install

```bash
dotnet add package EasyAF.Business.EF6
```

## Usage

```csharp
public class UserManager : EntityManager<MyDbContext, User>
{
public UserManager(MyDbContext context, IMessagePublisher publisher)
: base(context, publisher) { }

public override async Task OnInsertingAsync(User entity)
{
await base.OnInsertingAsync(entity); // audit fields
entity.IsActive = true;
}
}
```

Also includes `IdentifiableEntityManager`, `StatusEntityManager`, and `StateMachineEntityManager`. For EF Core, use `EasyAF.Business.EFCore`.

Requires `EasyAF.Data.EF6`.

## Documentation

- Docs: https://easyaf.dev/guides/business-layer
- Source: https://github.com/CloudNimble/EasyAF

## License

MIT © CloudNimble, Inc.
Loading